Sunday, August 29, 2010

XsltListViewWebPart – several XSLT tips

The XSL customizations of the XsltListViewWebPart in SharePoint 2010 are probably not a trivial thing. If you want to do something more complex with that the best starting point for reference materials is of course the SharePoint 2010 SDK - http://msdn.microsoft.com/en-us/library/ff604021.aspx. It provides extensive coverage on the topic, so I won’t repeat any of that in this posting. Here, I will concentrate on two things: the first one is a practical issue, which is probably the first one that you will encounter when customizing the XsltListViewWebPart’s XSL – how to hook your custom XSL to the XsltListViewWebPart. The thing is that you have not just one but four options for that – the XsltListViewWebPart itself exposes two properties for setting the custom XSL – XsltListViewWebPart.Xsl and XsltListViewWebPart.XslLink and also the SPView class has two properties with the very same names and obviously the same purpose. Well, that’s plenty and to quickly answer the two questions that may already have arisen – first – what has the SPView class to do with the XsltListViewWebPart – the answer is simple: the two classes are actually two representations of the same internal SharePoint entity (check a previous posting of mine on the subject - http://stefan-stanev-sharepoint-blog.blogspot.com/2010/02/listviewwebpart-spview-two-sides-of.html). And the second question – if the two classes are indeed representations of one and the same thing do these two sets of properties map to the same internal properties too – the answer here is no, the “Xsl” and “XslLink” properties of the XsltListViewWebPart are actually inherited from a base class (DataFormWebPart) that has no direct relation to list views and indeed the four properties are really independent from one another (and there are some differences in their usage despite the matching names as you will see below). One important thing here is that there is a specific precedence for their usage by the XsltListViewWebPart – the exact evaluation order is this:

  1. XsltListViewWebPart.XslLink
  2. XsltListViewWebPart.Xsl
  3. SPView.Xsl
  4. SPView.XslLink

Before starting with the exact specifics of using these properties I want to mention one other property of the XsltListViewWebPart class – CacheXslTimeOut. This is an integer property that specifies the cache time in seconds for the XslTransform object used by the XsltListViewWebPart. The caching of the XslTransform object is very useful because, of course, it boosts the performance. And the caching of the XslTransform also may be used or not used altogether depending on which of the “Xsl” or “XslLink” properties you use, which I think is important to know beforehand. One other thing here – when I tested the “caching” behavior of these properties I either changed the value of the properties in the case of the “Xsl” ones or changed the underlying XSL file in the case of the “XslLink” properties. The immediate reflection of the change to the rendering of the web part doesn’t necessarily mean that the cache is not used because it may simply mean that the change of the property invalidates the XslTransform cache. So in the short descriptions of the properties’ usage below I won’t mention that the XslTransform cache is not applied but simply that you see or don’t see immediately the change applied in the rendering of the XsltListViewWebPart. Of course for testing purposes you can always set the value of the CacheXslTimeOut property to 1 second so that you can quickly change the XSL and see the result immediately.

And now the details and specifics about the usage of the “XSL” properties:

  • XsltListViewWebPart.XslLink – you can change this with either the SharePoint UI (it appears in the XsltListViewWebPart’s toolpart) or programmatically with the SharePoint object model. Note here that unlike the XslLink property of the SPView class you can’t specify simply the name of a custom XSL file that resides in the system TEMPLATE\LAYOUTS\XSL folder (e.g. the standard main.xsl or a custom “custom.xsl”) – this won’t work (it may be a bit surprising). You have two options for specifying the path to your custom XSL file here – the first one is to specify a file under the TEMPLATE\LAYOUTS folder (it can be directly in that folder or any sub-folder below it, not just the “XSL” one) – and the path (rather URL in this case) should mandatorily start with “/_layouts/”. The other option is to reference an XSL file that resides on your site, for instance in a document library – then you can use either the site relative URL of the file or the server relative one. For example, if you have a “custom.xsl” in a library whose URL is “documents”, then the site relative URL will be “documents/custom.xsl” (no starting slash) and the server relative URL will be something like “/sites/mysite/documents/custom.xsl” (note the starting slash – the starting part of the URL depends on the server relative URL of your site). And about the caching behavior – interestingly enough it is different depending on whether you use an XSL file from the LAYOUTS folder or in a document library in the site – in the first case the changes to the referenced XSL file won’t be visible immediately, and in the second – they will be.
  • XsltListViewWebPart.Xsl – you can change this property with the object model, but the easier way to do this is with the SharePoint Designer. With it it should be easy to change the Xsl property even without deep understanding of XSL – you can use the enhanced UI of the SharePoint Designer to modify the styling and rendering of individual list columns or to apply conditional rendering on whole rows in the XsltListViewWebPart. The SharePoint Designer automatically populates the Xsl property with an XSL snippet containing one or several XSL templates depending on your exact customizations (this XSL also references the standard “main.xsl” and the templates in it are rather “overrides” of the standard row and column rendering XSL templates). The changes to the “Xsl” property are applied immediately regardless of the value of the CacheXslTimeOut property. If you think that this may pose a performance issue for you, you can always save the XSL contained in the “Xsl” property to an external XSL file which you can then reference with the XsltListViewWebPart.XslLink or SPView.XslLink properties.
  • SPView.Xsl – you can again change this property programmatically – for that you will need to get the hidden SPView instance associated with your XsltListViewWebPart (see the link to my posting on the subject above) or again the easier way to achieve that is to set the property in the view schema in the “schema.xml” file of your custom list template (custom “schema.xml” files can also be specified in ListInstance feature elements via the “CustomSchema” attribute). Note that below the “View” element in the “schema.xml” file you can have both “Xsl” and “XslLink” elements. One important note - you should provide the XSL in the “Xsl” element in the “schema.xml” and also in the SPView.Xsl property in an XML CDATA section. The changes to the SPView.Xsl property (those applied with code) are immediately visible in the XsltListViewWebPart regardless of the value of the CacheXslTimeOut property.
  • SPView.XslLink – you can change this property programmatically and also can set its value in the XslLink element in the view schema in the “schema.xml” file of your SharePoint list. Normally you provide only a file name in this property and the referenced XSL file with that name should exist in the system TEMPLATE\LAYOUTS\XSL folder. You can also reference files in sub-folders of the LAYOUTS\XSL folder and even files in the LAYOUTS folder itself – in the first case you set the “XslLink” property to “sub\custom.xsl” and in the second case - to “..\custom.xsl”. The XmlTransform caching is fully applied for the SPView.XslLink property depending on the value of the CacheXslTimeOut property. There is one extra thing here compared to the XsltListViewWebPart.XslLink property – if you set the CacheXslTimeOut property to 1 second you will need additionally to recycle the application pool (which will force the invalidation of the cache) and only after that you will see the changes to the underlying XSL file immediately in the rendering of the XsltListViewWebPart. This is also true if you have the CacheXslTimeOut  set to 1 second and you see the immediate changes but then set it to some higher value and then again reset it to 1 second – then you will no longer see the immediate changes until you recycle the application pool again. This means that the changing of the CacheXslTimeOut property itself doesn’t invalidate the caching of the XmlTransform in the case of the SPView.XslLink property.

So, this was the first topic that I wanted to talk about and about the second one I will demonstrate a short XSL snippet:

<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"

    xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:mycontrols="http://mycontrols" >

  <xsl:output method="html" indent="no"/>

  <xsl:decimal-format NaN=""/>

  <xsl:param name="XmlDefinition" select="."/>

 

  <xsl:template match="/">

    <xsl:value-of disable-output-escaping="yes" select="'&lt;%@ Register Tagprefix=&quot;asp&quot; Namespace=&quot;mycontrols.WebControls&quot; Assembly=&quot;mycontrols, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d03859869fe4a098&quot; %&gt;'"/>

    <mycontrols:MyControl runat="server" ListUrl="docs" />

 

    <table cellpadding="3">

      <tr>

        <xsl:for-each select="$XmlDefinition/ViewFields/FieldRef">

          <th><xsl:value-of select="@DisplayName"/></th>

        </xsl:for-each>

      </tr>

      <xsl:for-each select="/dsQueryResponse/Rows/Row">

        <tr>

          <xsl:variable name="row" select="." />

          <xsl:for-each select="$XmlDefinition/ViewFields/FieldRef">

            <xsl:variable name="fieldName" select="@Name" />

            <td>

             <xsl:choose>

                <xsl:when test="$fieldName='LinkFilenameNoMenu'">

                  <xsl:value-of select="$row/@FileLeafRef"/>

                </xsl:when>

                <xsl:otherwise>

                  <xsl:value-of select="$row/@*[name() = $fieldName]" disable-output-escaping="yes"/>

                </xsl:otherwise>

              </xsl:choose>

            </td>

          </xsl:for-each>

        </tr>

      </xsl:for-each>

    </table>

  </xsl:template>

</xsl:stylesheet>

You can see in the snippet that it makes its own custom rendering of the underlying SharePoint list data (not very good at that) and doesn’t even include the standard SharePoint “vwstyles.xsl” and “fldtypes.xsl” (it’s only for demonstration purposes and should be as short as possible). The important thing in it is in the very beginning of the body of its single XSL template definition – you can see there a somewhat concealed asp.net page “Register” directive and immediately after it an asp.net markup declaration of a server control. Note also that the “mycontrols” namespace of the server control element is declared in the root element of the XSL file. So, basically this means that you can place server controls inside the XSL and these will be instantiated by the XsltListViewWebPart and their logic will be executed server-side. As you see in the snippet I placed only one server control before the actual rendering of the list data, but you can place controls in every row or even cell that you render and you can provide some list item data to the properties of the server control or controls (there may be of course performance considerations because of the number of controls that can be created in this manner).

And to answer the question – how does the XsltListViewWebPart instantiate the server controls that you may place in the XSL. It is actually simple – the XsltListViewWebPart uses the XSL transformation to produce HTML markup from the source XML, it then checks whether there are occurrences of the “runat=server” token inside the HTML markup: if there are no occurrences, the HTML markup is simply rendered, otherwise the web part instantiates a server control using the asp.net TemplateControl.ParseControl method providing the raw HTML markup to its single parameter. The TemplateControl.ParseControl method as it name suggests parses asp.net markup and creates a server controls tree from it much like it happens when a normal “aspx” or “ascx” file gets compiled. So, with this small “trick” the XsltListViewWebPart allows you to place server controls and implement more complex server side logic inside your custom XSL. And one limitation to this approach – you can’t use user controls (ascx files in the CONTROLTEMPLATES or LAYOUTS system folders) inside the XSL (server controls that use user controls internally with the TemplateControl.LoadControl method will also fail to instantiate their user controls).

83 comments:

  1. Stefan - Great post! Quick question - if you try to do this from the Sandbox, how would your "Register" declaration change? I am trying to implement this but can't get past that part.

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. Hi,
    I was searching the Internet and found your awesome blog. I have studies
    many Sharepoint books on the market,If read your this site this is very
    informative, and your site gives planty of knowledge about Sharepoint.
    Thank You
    SharePoint branding

    ReplyDelete
  4. Hi Anonymous,
    this is an interesting question. Several things to start with - you cannot reference directly server controls from sandbox solutions. Another thing is that you can use web parts from sandbox solutions but you can't place them directly on your page (or in the XLV's XSL in our case). You need to use the standard "proxy" SPUserCodeWebPart for that. So, the server tag will look like:
    <SharePointWebParts:SPUserCodeWebPart runat="server" AssemblyFullName="SandboxWebPart, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9d97fc6db9e2bfbf" SolutionId="3f55adf3-9680-4e2b-848d-fab9589aaa1e" TypeFullName="SandboxWebPart.WebPart1.WebPart1" />
    You need to put the correct values for your sandbox web part in the AssemblyFullName, TypeFullName and SolutionId properties. Also you will have to add a register directive for the Microsoft.SharePoint.WebPartPages namespace (from the standard Microsoft.SharePoint assembly). And finally you will also need a XML namespace declaration for the SharePointWebParts tag prefix - you can put this in the root element of the XSL file:
    xmlns:SharePointWebParts="Microsoft.SharePoint.WebPartPages"

    ReplyDelete
  5. thanks very much - I will give that a try.

    ReplyDelete
  6. Hi Stefan,
    Thanks for your informative post.
    I was hoping you could help me. I have a site collection where each site contains a document library, and I have customised a view in SharePoint Designer 2010 for one of the libraries, and I would like to copy the view customisation to each document library. When i inspect the customised view's Xsl property, I can see the customisations made in Designer, however can I copy this property to the Xsl property of each other Document Library via code? This would save me having to open each Document Library in SharePoint Designer and manually apply the changes? If I set the Xsl Property in code, how do I save it back to the XsltLstViewWebPart? Thanks for you help.

    ReplyDelete
  7. You can use something like this code (I quickly wrote it using some LINQ, but haven't tested it):

    private static void SetXslRecursively(SPSite site, string xsl, string viewFileSiteRelativeUrl)
    {
    // viewFileSiteRelativeUrl - should be something like mydocs/forms/allitems.aspx - the site relative url of the file of the view containing your XsltListFormWebPart

    // get all webs
    site.AllWebs.Cast<SPWeb>()
    // get the view file from every web (every web should have this document library with this view)
    .Select(web => web.GetFile(viewFileSiteRelativeUrl))
    .Where(file => file.Exists)
    .ToList()
    // iterate the files
    .ForEach(file =>
    {
    // get the SPLimitedWebPartManager for the file
    SPLimitedWebPartManager manager = file.GetLimitedWebPartManager(System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared);
    // get the XsltListFormWebPart - normally it is the only one in the file
    XsltListFormWebPart webPart = manager.WebParts.OfType<XsltListFormWebPart>().FirstOrDefault();
    if (webPart != null)
    {
    // set the Xsl property
    webPart.Xsl = xsl;
    // update the web part
    manager.SaveChanges(webPart);
    }
    }
    );
    }

    ReplyDelete
  8. Hi Stefan, Great post,
    a quick question, How can I set a value of CacheXslTimeOut property of a XSL List view web part? This property is not available in a web part editor of XSL List Web Part. Because the "Export" option is not available with XSL List View web part, I can't really export it out as .webpart file and then set the value of CacheXslTimeOut property in the file. So how do I set a value of this property?

    ReplyDelete
  9. The property is actually available in editor tool-parts of the XLV web part. It appears in the "miscellaneous" section and its title is "Data View Caching Time-out (seconds)". You can also try this tool of mine - http://webpartmanager.codeplex.com/ - it allows you to change the properties of the web parts, import and export web parts (even web parts for which you don't see the "export" command in the UI), export the web parts in a page to a "module" feature, etc.

    ReplyDelete
  10. Thanks Stefan for your answer promptly.
    Another question,
    In my site there is a list called "Employees" and in this list there is a "Department" column. For this list We have created a List View with 'Boxed, no labels' style and it has a Group By Department column. All the departments are collapsed by default and when expanding a particular department, it uses AJAX to fetch the employees of that department.
    Now we wanted to make small changes to the way it was rendering the employees in this list view. By default for every employee it uses borders that we did not want and few other small tweaks. So I created XSL stylesheet, overridden few templates, deployed the file in the XSL folder on the server and then i have specified the path to the file in XSL Link property of the Employees list web part. (Here is the sample of xsl file - https://docs.google.com/document/pub?id=1ULali4GzOwRciW1zhoPRH7JTjWFxa-ugy0rrxhG1t4g). It is all working fine except when I expand a department node, it takes about 3-4 seconds to retrieve the list. I don't know why it takes that much time because it takes only a second in the original Group By view which is by default using standard xsl files (main.xsl, vwstyles.xsl etc) on the server.
    Maybe the XSL file is not being cached or something. I have checked the 'Data View Caching Time-out' property the value is 86400 seconds by default so in theory the file should be cached.

    ReplyDelete
  11. Hi Hitesh,
    I see that you used SharePoint Designer to customize the XSL for the XLV web part and then saved it as a file and set the web part's XslLink property to reference the file. I don't know what may be causing this big delay but I can advise you to try one other thing - instead of setting the XLV's XslLink property, try to set the associated hidden SPView's XslLink property. You can achieve this very easily with the "web part manager" tool of mine - http://webpartmanager.codeplex.com. So the steps are as follows - 1. locate your page in the tree view of the tool; 2. expand the page node and select your XLV web part which will appear below the page node; 3. empty the XslLink property (and the Xsl property if it has some value) and save the web part using the "actions" menu; 4. expand the web part's node - below it you will see a SPView node for the hidden associated list view of the web part; 5. set the XslLink property of the SPView to reference your XSL file (note that you should enter only the file's name, not a URL like /_layouts/XSL/custom.xsl as it is the case for the XLV's XslLink property - check the posting for details); 6. update the view from the "actions" menu. (you may need to recycle the application pool to see the change.)
    Let me know if this helps.

    ReplyDelete
  12. Thanks for your great post. I have one requirement to customize all the views that are displayed on the home page of the site in a tabular format with borders.

    From different blogs, i understood that we need to use XSL for customizing the view. So i decided to create custom xsl and point this xsl in the web part properties.

    But, i am not sure how to proceed with that, meaning how to create custom xsl.

    Could you please suggest on how to proceed with custom XSL?

    Thanks
    Chandrasekaran C N

    ReplyDelete
  13. Hi Stefan,
    Thank you so much. I have followed your steps and yes it has fixed the problem. I don't know how would I have solved the problem without your tool and advice.

    Thanks
    Hitesh

    ReplyDelete
  14. Hi Chandrasekaran,
    I think that the best starting point is SharePoint Designer 2010. You can open the default view (e.g. "AllItems.aspx") of your list in it and can start customizing its look and feel in design mode. If you are able to make your changes in design mode only (it's a bit tricky but once you get used to it it is pretty straight forward), then your task will be almost complete - the only thing left will be to switch to "code" view and get the generated XSL from the Xsl property of the XLV web part (it appears in the HTML markup). Then you can save this XSL to a file in the TEMPLATE\LAYOUTS\XSL folder and reuse it in other lists. You can set the SPView.XslLink property with code to reference this file, or you can set the corresponding XslLink element in your custom schema.xml. This approach is pretty neat - if you examine the XSL generated by the SharePoint designer you will find out that it includes the standard "main.xsl" and then depending on your changes overrides some of the xsl templates used in the vwstyles.xsl and fldtypes.xsl files. For instance - if you select an item row in your XLV web part and select "Conditional Formatting -> Format Row" from the ribbon (you can specify some dummy condition like @ID > 0 which will be true for all items) and apply some styling - e.g. change the background color, when you switch to "code" view you will see that there will be a new xsl template element whose declaration will look like this - <xsl:template mode="Item" match="Row" ... This template will basically render all item rows (the TR HTML elements for each list item) in your XLV web part and you can further make some changes to it in "code" view. When you do the same thing for the header row (containing the column names) you will see a xsl template with a declaration like <xsl:template name="View_Default_RootTemplate" mode="RootTemplate" match="View" ... This template is responsible for the rendering of the outer TABLE HTML element that contains the header and item TR elements, so if you want you can add your customization there too.
    Check also this MSDN article - http://msdn.microsoft.com/en-us/library/ff602042.aspx - to get a clue about the source XML that is provided to the XSL transform object of the web part and also the schema XML contained in the $XmlDefinition parameter that is available in the standard (and generated) XSL files.

    ReplyDelete
  15. Hi, great post! Is it possible to use this server control rendering technique for the custom field rendering in List view page. I'm using a separate xsl file for the custom field. Thx...

    ReplyDelete
  16. Hi Anonymous,
    this is an interesting question. And the answer is that it actually (surprisingly) works. I created a test XSL file in the LAYOUTS/XSL folder - fldtypes_test.xsl and added this XSL template to it: <xsl:template match="FieldRef[@ID='f9485f83-752b-437f-b4af-4fc32a3556c5']" mode="Text_body">. As you see it targets not a specific field type but rather a specific field (matched by its ID) - the scenario is a little different but the idea is the same. I simply added the asp.net Register directive and then declared the server control in the XSL template and ... it worked. I thought at first that it wouldn't work, because the asp.net Register directive should be at the very beginning of the markup and that it shouldn't also occur more than once (and the custom field rendering template is invoked to display the field value of every list item that the XLV renders). But obviously this doesn't result in an error and it works just fine. Some extra logic can be added though that makes some checks and outputs the Render directive just once (only for the first row that the web part shows).

    ReplyDelete
  17. Hi Stefan,

    This is Hitesh here again with one more question. On the home page in my site, I have added a List Web Part. When I access the home page in a browser and click anywhere in that list, it displays the "List Tool" ribbon group which has "Items" and "List" ribbons. I do NOT want these ribbons at all when clicking anywhere in the list. How do I achieve this? Should I disable the click event on the list so these ribbons do NOT appear? How do I disable the click event on the list? Or What should I do to hide these ribbons when clicking anywhere on the list?

    Basically I want it to behave same as content query web part. In content query web part, if you click anywhere in it, it doesn't show up any extra ribbons. I want the same behavior with list web part. I just want to use it purely for display purpose only. I don't want it to allow the management of the list by showing the ribbons.

    Thanks
    Hitesh

    ReplyDelete
  18. Hi Hitesh,
    this is an issue that I've also come across. I am onto something and will probably dedicate a separate posting to it one of these days. Stay tuned.

    ReplyDelete
  19. Thanks Stefan, Looking forward to the solution that you are going to suggest.

    ReplyDelete
  20. Una pregunta
    SI creo mi webpart por codigo y la agrego osea
    This.controls.add(MiXsltListViewWebPart);

    No me aparece las herramientas de la lista osea no me puedo envar alertas ni demas opciones.

    Mi idea era crear una webpart dinamica que me mostra X lista segun un filtro y poder asignar permisos, alertas etc etc.

    que puedo hacer?

    Muy buen POST!!!

    ReplyDelete
  21. Hi Anonymous,
    I tried to translate your question in google translate, and it seems that it is about adding the XLV web part in a custom control and the consequent problem with the ribbon not showing (I saw another similar question in the other posting about the XLV - maybe it was you again). Unfortunately I don't know how this can be fixed or whether there is a fix for it at all.

    ReplyDelete
  22. Thanks Stefan for you time and try to translate my question. I´m Anonymous

    your blog is awesome!!!!!!!

    ReplyDelete
  23. Instead of customizing an XsltListViewWebPart instance, is there a way to pack xsl customizations in with a list definition in a sandboxed solution? The List CAML element in a list definition has Views that define the query. I see the XslLink element as a sub-element to View, but changing it from "main.xsl" to "SiteAssets/xsl/MyXsl.xsl" is not working for me. I get a generic error on the AllItems page for the list.

    Thanks,
    Lou Estrada

    ReplyDelete
  24. Hi Anonymous,
    You can use the other option for setting the xslt in the list view - the Xsl element like:

    <Xsl><![CDATA[<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:import href="/docs5/main.xsl"/>
    </xsl:stylesheet>
    ]]></Xsl>

    note that this xslt snippet contains only an xsl:import statement to the main xsl file that you want to place in a document library - in my case the location is /docs5/main.xsl - this is actually the site relative URL and not the server relative one (my test site was under http://myserver/sites/test).

    ReplyDelete
  25. My problem, however, is that I cannot seem to set the Xsl or XslLink properties from a sandboxed solution during deployment or feature activation. I am trying to avoid manual (Designer) steps in deploying my solution. So in your solution above, I would have to crack open Designer to set the Xsl like you showed.

    I tried setting the XslLink in the list definition (elements.xml) to no avail (only looks in _layouts/xsl).

    I tried setting the Xsl property of the SPView object in a feature receiver. Setting the Xsl of the SPView renders the custom xsl into the XsltListViewWebPart's GhostedXsl property, but it does not render properly. This is the closest I have come to a solution, however, as changing the property to from GhostedXsl to simply Xsl in Designer works. I cannot access the webpart itself in sandboxed code (am I wrong?), so I may be stuck.

    Do you have any other ideas as to how I can deploy this without manual steps?

    Your time and insights are much appreciated.

    Lou Estrada

    ReplyDelete
  26. Hi Lou,
    you need to put the Xsl element that I posted in my previous comment in your schema.xml file (at the same level as you have your XslLink element there). This element will effectively set the Xsl property of the SPView instance, not of the associated XLV web part (which you can edit in the SharePoint designer). Can you try this and let me know if it works for you.
    Stefan

    ReplyDelete
  27. Stefan,

    You are right, I meant schema.xml in my last comment.

    I did as you said and added the Xsl element to the View in my list's schema.xml. I have it successfully pointing to my xsl in my document library. The documentation led me astray (only XslLink listed as a child element), but it is starting to make more sense how this works... http://msdn.microsoft.com/en-us/library/ms438338.aspx

    THANK YOU!

    Lou Estrada

    ReplyDelete
  28. Hi Stefan,

    Thanks for the great posts on the subject!

    Have you found a way to use XSLT 2.0 functions (like replace) in the XSLTs of XsltListViewWebPart? Solutions without custom assemblies would be preferred.

    Peter

    ReplyDelete
  29. Hi Peter,
    I browsed around and found out the XSLT 2.0 is not supported in the .NET framework, at least not in .NET 3.5 which is used in SharePoint 2010. So the only option available for the XLV web part is to use XSL templates that can mimic the behavior of the functions available in XSLT 2.0 (which is quite cumbersome though). For instance - a string replacing XSL template is available in the standard ContentQueryMain.xsl called OuterTemplate.Replace - this one can be copied and used in a custom XSL file for the XLV web part. Apart from that, there is a built-in XSLT extension class, that can be used with the "ddwrt" namespace - Microsoft.SharePoint.WebPartPages.DataFormDdwRuntime and its base class Microsoft.SharePoint.WebPartPages.BaseDdwRuntime, containing about forty useful methods.
    Stefan

    ReplyDelete
  30. Hi Hitesh,

    "I do NOT want these ribbons at all when clicking anywhere in the list. How do I achieve this?"

    You should set the TabularView="FALSE" on the View element of the XsltListViewWebPart as described on Chris O'Connor's blog:
    XsltListViewWebPart – remove checkboxes
    http://sharepointroot.com/2011/03/14/xsltlistviewwebpart-remove-checkboxes/

    (Stefan might be blogged about it in the meantime as well.)

    A bit more info here about TabularView:
    SPView.TabularView Property
    http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spview.tabularview.aspx

    Hope it helps.

    Peter

    ReplyDelete
  31. Hello,
    Could you provide the source code for the project MyControl that you are using in the snippet ?

    Thank you

    ReplyDelete
  32. Hi Anonymous,
    I searched around on my dev machine but I couldn't find it, I think I deleted it long ago. It was a dummy control actually, rendering a single asp:Button control as far as I can remember and I created it only to demonstrate that it is in fact possible to embed server controls inside the XSL of the XLV web part.

    ReplyDelete
  33. Hi Stefan,

    I run into a problem when using a custom xslt on my view definition in the schema.xml (xsllink). The rendering itself works fine, but when users create a new view based on my orginal one, my custom xsllink is not retained in the new view. Have you encountered this issue?

    ReplyDelete
  34. Hi Anonymous,
    I hadn't encountered this issue before, but I quickly reproduced it. I played a bit with it and couldn't find a solution, it may well be this way by design, though it's really cumbersome. There is actually a way using the UI alone to get this the right way, but you need an extra step for that. You have to get the page to edit mode, switch on the XLV's edit pane and change the "Selected View" drop-down to your original view.
    I also tested with setting the custom XslLink of the BaseViewID="0" View element in the schema.xml:
    <View BaseViewID="0" Type="HTML" MobileView="TRUE" TabularView="FALSE">
    (the one that is used as a base for all HTML views) but still it didn't work. Actually there was an interesting effect from this one - on a normal web part page, after I added a XLV web part, the web part at first displayed the custom XSLT but after I saved the page it switched back to the default main.xsl

    ReplyDelete
  35. I only could find two ways to fix the view using client tools: the one you describe and using SP Designer (adding missing XslLink fragment in view). In the context, i can't ask the users to do that. I looked and there are no events triggered upon view creation. I looking at adding a new custom action in the ribbon to "Apply style". Oh well.
    Thanks for your help.

    ReplyDelete
  36. Hi Anonymous,
    if the users create the views with the standard /_layouts/ViewNew.aspx application page you can try another hack. The ViewNew.aspx creates the new list view in a rather strange way - when you click the OK button - instead of a regular postback the form goes with an HTTP POST request to /_vti_bin/owssvr.dll - this is an unmanaged ISAPI extension which is part of SharePoint. The call to owssvr.dll effectively creates the list view and returns a 302 HTTP code to redirect to the page of the newly created view. You can check the POST parameters that the ViewNew.aspx sends to the owssvr.dll call and the response by the latter with the "fiddler" utility. In theory it should be possible to hook onto the owssvr.dll call with a managed HTTP module (leveraging the integrated pipeline functionality of IIS - though I am not 100% sure whether that will be possible in the case of the unmanaged owssvr.dll ISAPI extension) and add the extra XslLink setting logic when you detect the view creation type of call onto owssvr.dll. Let me know if this will be of help of you and if you have other questions in case you go for this solution.

    ReplyDelete
  37. First of all, nice blog topic! Your page is by far the most helpful for mid to advanced XLV editing that I've found after 10+ click throughs of google search results.

    Now my question... How do you use the XLV with a custom XSL file akin to what you would link to in a CQWP?

    And is the XLV the only list viewing web part that has mobile extensions?

    ReplyDelete
  38. Hi Anonymous,
    this is an interesting question (actually two questions, but I won't comment on the one about the mobile extensions, because I haven't done any specific research about that). And about the similarities of using XSL file/files with the XLV web part and the CQWP - this is really a very broad subject so that probably requires a separate blog posting, so I will just briefly mention some of the key things about it here. So, in the CQWP you have the so called item styles, basically backed up by separate XSL templates in the standard ItemStyle.xsl file. For the XLV web part we have a similar concept which is called view styles. You can see them directly in the SharePoint UI when you select the "modify view" button in the ribbon and open the "edit view" page, where there is a dedicated section called "styles". The definition and rendering support for the view styles is contained in two files with the same name but different extensions: TEMPLATE\GLOBAL\XML\vwstyles.xml and TEMPLATE\LAYOUTS\XSL\vwstyles.xsl. The first one defines the available view styles for all lists in the current site. Actually when you modify the file on this location, the changes affect the whole farm. Basically if you want to create a custom view style you need to copy one of the existing ViewStyle elements in the XML and assign to its ID attribute a unique integer value (you need to put some meaningful value in the DisplayName attribute of course); you can ignore all the CAML inside the ViewStyle element because with the XLV web part this is not involved in the actual rendering (it is a remnant from the old-fashioned SharePoint 2007 and 2003 ListView web part type rendering). As I said, if you edit the file in the GLOBAL\XML folder, this will impact your entire farm. You have the option though to create a copy of this file and place it the XML subfolder (where your ONET.XML file resides) of your custom site definition(s) - in this case the changes will be available only in the sites based on this site definition. After you have your custom view style defined you can proceed with implementing a custom rendering for it - you again have two options here - to either modify the standard vwstyles.xsl file (which is obviously a bad idea) or to create a file in the same location with this pattern vwstyle*.xsl - which is a standard built-in mechanism in SharePoint to extend the XLV rendering capabilities. As to what XSLT templates you should provide in this extra vwstyles XSL file - you can check the standard vwstyles.xsl file which already contains XSLT templates that handle the different view styles selected for the current XLV web part (you can play first in the standard UI by changing the standard view styles to see how the rendering of the web part changes). Unfortunately this is not the whole story about the "rendering styles" in the XLV. Unlike the CQWP there is one more style level here - the so called field styles - basically you can think of the list view as a table, the view style is responsible for the row rendering and the field style is responsible for the cell rendering (whereas in the CQWP you only have one level - the item style). Of course you can define your view style XSL rendering template in a way that it ignores completely the field styles, but in reality all standard view styles use the field styles. These manage the rendering of the field values of the list items based normally on the type of the list field - the file that holds the XSL templates for that is called fldtypes.xsl. As with the vwstyles.xsl file this one can be extended in the very same manner - using new xsl file with this template fldtypes*.xsl in the same physical location.
    So, as you can see the whole thing is not very trivial and not quite the same as with the CQWP but still, there is plenty of space and built-in capabilities for extending the standard functionality.

    ReplyDelete
  39. Now have a look into below link.


    http://maulikdhorajia.blogspot.com/2011/06/sharepoint-2010-xsltlistviewwebpart.html

    ReplyDelete
  40. Stefan,
    Using Office 365 / SP Online, we can't access /_layouts. Linking an xlv to an site stored xsl file (with the relative url forward slash by the way), works when logged in but anonymous users get a permissions error. I understand this is related to the xlv referencing the cached view, but turning off caching in the toolpart doesn't work.
    Can you suggest a workaround using the ui, that doesn't require adding the xsl inline via SPD?

    ReplyDelete
  41. Hi Meusfilia,
    I can't test this on SP online at this moment but I can give you another hint - can you check with setting the Xsl property of the XLV with an XSLT that contains an xsl:import expression - there was an example in one of the comments above:

    <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:import href="/docs5/main.xsl"/>
    </xsl:stylesheet>

    This way you can have all the transformations in an external XSL file. I have tested this actually with the SPView.Xsl property and it works for sure, though I don't know whether it will work in your case with anonymous access. And the changing of the SPView.Xsl property is not as straight-forward as the changing of the XLV.Xsl property which can be easily done with the SPD. For the SPView.Xsl property you should either have it in a custom list schema.xml or you will have to change it programmatically (e.g. with the client object model in the case of SP online).
    Let me know if any of these two work for you.

    Greets
    Stefan

    ReplyDelete
  42. Hi Stefan,
    So are you saying the xsl link in the web part properties added in the ui should be to an xsl file containing an xsl:import link to the real xsl file you want applied?

    ReplyDelete
  43. Hi,
    no, the sample XSL should be set to the "Xsl" property of the web part (you don't point the "XslLink" property to a file). The "Xsl" property is the property of the XLV web part that gets populated when you use the SPD to make customization to the look & feel of the web part. In SPD - when you open the page with the XLV for editing and switch to "code" view you will see the raw XSL in the "Xsl" property and will be able to edit it directly replacing it with this snippet.
    Let me know if this works in your case.
    Greets
    Stefan

    ReplyDelete
  44. Hi Stefan.

    Please save me from an issue that i am facing in my sharepoint 2010 site. I am using XSLT List View webpart on my webpart page. I am giving XSLT file link for rendering the content.

    My xslt list view webpart fails at random times. dont know the reason. It says, "Unable to display this webpart. To troubleshoot this problem, open the web page in microsoft sharepoint foundation compatible HTML editor such as microsoft sharepoint designer. If the problem persists, contact your web server administrator."

    hoever, if i refresh the page after this error, my webpart works fine. dont know why this error comes and why it works if i refresh.

    please help me out.

    regards
    raj

    ReplyDelete
  45. Hi Raj,
    can you give some more details about your setup - do you use SharePoint Online or SP 2010 or SP foundation. Another important detail: what is the location of your custom XSLT file - the TEMPLATES\LAYOUTS folder or in a document library of the site itself. If possible it will be best to send me your custom XSLT file (you can use this email - code@stefan-stanev.com). Last thing - have you configured your site to use anonymous access?

    Greets
    Stefan

    ReplyDelete
  46. Hi Stefan,

    I'm wondering if you could help me out with something that I've been struggling with for a while...

    I'm trying to create a custom vwstyles*.xsl file with which I'll be able to apply some global XSL changes. The first such change is to override the EmptyTemplate template (which appears at the bottom of vwstyles.xsl).

    I've created a custom vwstyles_test.xsl with the necessary updated template, and tried to add a 'priority' value to it also so that it takes precedence - but I'm having no luck getting it working.

    Have you any ideas on how I could achieve this?

    Thanks,
    Glyn

    ReplyDelete
  47. Hi Stefan - a quick update on my previous comment. I think I've narrowed my problem down to the 'import precedence' of the XSL files. i.e. vwstyles.xsl is importing my vwstyles*.xsl - but the named template (EmptyTemplate) in the original vwstyles has a higher import precedence and therefore my attempt to override it is failing.

    I guess it comes down to - is it possible to override a named (non matching) template with an imported stylesheet!?

    Thanks,
    Glyn

    ReplyDelete
  48. Hey Stefan,

    Any idea if XslTransform objects are cached in the Sharepoint object cache (and thus affect by cache size in web.config) or somewhere else?

    @Glyn: I guess you need to customise main.xsl :P

    Cheers,
    Nick

    ReplyDelete
  49. Hi Glyn,
    (a little bit late after some long holidays) - the "EmptyTemplate" template is invoked using the xsl:call-template directive, so there is no way that you can specify a priority for the version that should be called. The actual priority is the place in the XSLT where the template appears. The problem is that your modified version gets included after the standard vwstyles.xsl (the vwstyles*.xsl files get included in the main.xsl file with some modifications of the original version in the file system with some code - you can check these methods in the .NET reflector: WSSXmlUrlResolver.ConvertGhostedXsl and XsltListViewWebPart.PreProcessCachedXSL). The only solution in your case is to either modify the standard vwstyles.xsl or the standard main.xsl. In case of the latter you can directly include your vwstyles*.xsl (or it can be with any other name now) file just above the other xsl:include-s.
    Greets
    Stefan

    ReplyDelete
  50. Hi Anonymous,
    Judging from the BaseXsltListWebPart.DfwpCacheRead and BaseXsltListWebPart.DfwpCacheWrite methods (or rather their base implementations in the DataFormWebPart class) the XslTransform-s are cached directly in the asp.net cache (System.Web.Caching.Cache), so the SP object cache settings shouldn't affect anything here. In these methods there is also the possibility for the web part's cache to be used (WebPart.PartCacheRead and WebPart.PartCacheWrite), but I saw that they also use ultimately the asp.net cache, provided that you have this default setting in the web.config: <WebPartCache Storage="CacheObject" />
    Hope this helps.
    Greets
    Stefan

    ReplyDelete
  51. Thanks Stefan, information really appreciated.

    Cheers,
    Nick

    ReplyDelete
  52. Hi Stefan - many thanks for the reply! I was hoping to avoid modifying the out of the box stylesheets as I believe that brings 'official supportability' of the system into question. However, it looks like there are no other options in this case!

    Thanks,
    Glyn

    ReplyDelete
  53. Does anyone have an explanation for the fact that when I try to access my xsllistviewwebpart on an anonymous site it doesn't work (access denied error). Yet I can retrieve the xsl directly by url as an anonymous user. According to other posts on this subject there's a bug in SP2010 which doesn't allow anonymous users to transform xsl. All settings are configured right (permissions, etc.), yet I only get the right result when logged on.
    Any help on how to get the webpart to function properly would be appreciated.

    Thanks,
    Esther

    ReplyDelete
  54. Hi Esther,
    you didn't mention how exactly you use your custom XSL in the XLV. It is obvously a custom XSL file that you use so I presume you must be setting the XslLink property of either the XLV web part or the underlying SPView instance. The other interesting thing is whether the XLS file is in the /LAYOUTS folder or in a document library. I suspect that it is the latter case, there was actually a very similar to your case mentioned in some of the previous comments of this posting, the only difference was that the issue was in SharePoint online. Can you check the comments above from the user meusfilia, and also check this thread - http://community.office365.com/en-us/f/154/t/13670.aspx - it includes a work-around (a bit awkward) in the end. If your problem is the same it is caused by some SharePoint 2010 bug (or feature maybe). Let me know if this helps you with your issue, or else I will check deeper into that.

    Greets
    Stefan

    ReplyDelete
  55. Hi Stefan,
    Thank you for your quick response. I've tried the workaround from the link you suggested where I add a new (extra) xsl in which I put a xsl-include-tag which references my custom xsl. I've also tried the same with an import-tag just to be sure but neither helps unfortunately. To address the missing information: you're right...The Webpart I add to the page by selecting the Category List & Libraries and selecting the list on which I want to base the webpart. I set the xsllink property on the web part and reference my custom xsl which is in the Style Library.

    Greetings,
    Esther.

    ReplyDelete
  56. Hi Esther,
    I checked this issue again - the exact problem is that in anonymous mode this method - SPRequest.UpdateWebPartCache throws an UnauthorizedAccessException exception. This happens for both the "Xsl" and "XslLink" properties of the XLV web part (if one of them has a non-empty value). The implications here are quite serious because all customizations to the XLV web parts made using the SharePoint designer won't work either in anonymous mode. This is because the customizations with the SPD are persisted in the "Xsl" property of the XLV web part.
    If you can't use the "Xsl" and the "XslLink" properties of the XLV web part, the only option left is to use the "Xsl" or "XslLink" properties of the underlying SPView instance. The SPView.XslLink property can be ruled out in your case because with it you can only reference files in the "LAYOUTS" subfolder of the SharePoint hive and not files in document libraries in your site (which is the idea in the first place). Luckily the last alternative: the SPView.Xsl property provides a real work-around to your issue - you have to use a short XSL snippet in it which only includes your actual XSL file from your document library. I had shown this technique in one of the previous comments of this posting, but I am going to paste the snippet you need again:

    <![CDATA[<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:import href="/docs5/main.xsl"/>
    </xsl:stylesheet>
    ]]>

    Note that the the XSL code is enclosed in a CDATA section. The sample code references an XSL document in this location "docs5/main.xsl", which you will need to modify to point to the real location of your XSL file in your site.
    You can change the SPView.Xsl property using code or custom list instance definition with custom schema.xml; yet another option for quick testing is to use my Web Part Manager tool: http://webpartmanager.codeplex.com/
    In it you will need to locate the page with the web part in the tree hierarchy, below it you will have to expand the node of the XLV web part, and below the node as a child node you will see the node of the corresponding SPView instance. After you change its Xsl property, right click the SPView node in the tree view and click the "Update View" command in the context menu. Let me know if this was of help for you.

    Greets
    Stefan

    ReplyDelete
  57. Stefan,

    Your answer above has shed some light on our own problem regarding xsl transformation for anonymous users, but I think it's slightly different than Esther's. What I've done is created a view in a document library, then edited the XsltListViewWebPart in SP Designer so that the Title column links to the file instead of the name field. It was a requirement by a client.

    The view worked fine for a while, then we started getting the same "Access denied." message. The workaround was to edit the view with an authorized user, save it, refresh the view with authorized user, then anonymous users could view it. The problem is that it breaks again after a short time. Since we're not referencing an xsl file, is there any solution for our situation?

    I've been following this thread about the problem as well: http://social.technet.microsoft.com/Forums/en-US/sharepoint2010customization/thread/3d95f279-91c0-47be-b7b9-3a0f83ff4f8c/

    ReplyDelete
    Replies
    1. Hi Matt,
      Unfortunately, this is a bug (or feature, depending on the perspective) of the XLV web part. I mentioned in my reply to Esther that the issue is affecting all modifications made to the XSLT of the XLV web part using the SharePoint designer. This is because the SPD persists its customizations of the XSLT in the XsltListViewWebPart.Xsl property. In the forum thread that you sent it was correctly noted that the web part crashes because it tries to cache the XSL transform, which obviously fails for anonymous users (once it's cached it works for subsequent anonymous requests, but it will fail again after the cache expires).
      Again in my reply to Esther, I wrote about a possible work-around, which includes the clearing of the XsltListViewWebPart.Xsl property (it should be empty, the same as the XsltListViewWebPart.XslLink property) and moving the customized XSL to the associated SPView instance - actually to the SPView.Xsl property (note that you will have to enclose the XSL with a CDATA section there). Note also, that you can directly place all the customized XSL in the SPView.Xsl property without it being necessary to use an external XSLT file, as I had suggested to Esther. This can be easily achieved using my "web part manager" tool (check the above comments for more details). I know that this is a pretty cumbersome solution and you will have to do additional manual work especially in case you have to do continuously make changes with the SPD (swapping the XSL between the two properties), but as far as I know this is the only working solution for anonymous access.
      Let me know if you have other questions.

      Greets
      Stefan

      Delete
  58. Thanks for the quick answer, Stefan. I just wanted to make sure we were experiencing the same bug/feature as Esther. That is indeed quite a bit of work, but we'll do whatever we need to to make the clients happy.

    ReplyDelete
  59. Hi Stefan,

    Very nice article.

    I am facing the same issue as Raj. Were you able to resolve his issue? I am using SharePoint Server 2010. not sure of what do you mean by Custom XSLT file. I am using a form Library with 5 views. And I have set some custom code in these views. And also on home page of my site I am displaying these 5 views with some custom XSLT for the Add Document button.

    Can you please help me?

    Regards
    P

    ReplyDelete
  60. Hi Pooja,
    I also don't know the exact reason for this issue, but a good starting point will be to try to locate this error in the SharePoint log files. If you can find it in the log files and there is a stack trace for it there, it would be much easier to pin-point the exact cause. You can also paste the stack trace as another comment here and I will investigate it too.

    Greets
    Stefan

    ReplyDelete
  61. Hi Stefan,

    Is there a way to programatically convert ListViewWebPart to XsltListViewWebPart? Are there any possible issues/implications related to the conversion (if possible)?

    ReplyDelete
  62. Hi Anonymous,
    here is a small helper class that I have used: https://sites.google.com/site/stefanstanev/sharepoint-samples-1/LVtoXLV.cs
    it contains one public method that accepts two parameters: SPLimitedWebPartManager and ListViewWebPart, it basically creates a new XLV web part in the same web part page using (or at least trying to use) the same settings as in the existing LV web part. It doesn't modify or delete the existing LV web part.
    The method of copying the settings is to copy the schema of the underlying SPView instance of the existing LV web part to the respective SPView instance of the new XLV web part.
    As it is the code shouldn't have any negative implications and as for any possible issues - it may not create an exact copy between the LV and XLV web parts in all cases.
    Let me know if it works in your case.

    Greetings
    Stefan

    ReplyDelete
  63. Thanks Stefan.. it was of great help

    ReplyDelete
  64. Hey. Great stuff! Question about provisioning XSLTListViewWebPart and setting the XslLink property in the context of a Sandboxed Solution: http://sharepoint.stackexchange.com/questions/33850/provision-xsltlistviewwebpart-with-alluserswebpart-or-view-and-customize-the

    ReplyDelete
  65. Hi Brian,
    From my experience (and tests) I think that the only possibility using only OOB stuff is the one mentioned in the first comment under your question in stackexchange. Using a CDATA block with "webParts" XML snippet under the "View" element allows you to only set the standard commonplace web part properties like "Title" and "Description". On the other hand the other option - to create custom views in the schema.xml of the parent list setting the XslLink elements with the desired locations - is also not very good, because you can't always foresee up front what customizations of the look and feel you may want to have in the presentation of your list. So ... I think that you will have to consider some custom solution with some extra code, maybe in a feature receiver.

    Greets
    Stefan

    ReplyDelete
  66. Stefan, agreed. Also, the XslLink on the parent list's view only works for Farm solutions since I think it requires that the xsl be deployed under 14/Template/Layouts/XSL. Appears only option for Sandbox Solutions would be the approach, which stinks for it's own reasons. Are you on Twitter?

    ReplyDelete
  67. Hi Stefan! Is approach with server controls still works if define xsl or xsllink in view definition? If I do it after list instance creation(list is created using custom schema with view defined in it) GhostedXslLink is set in XSLV. And due to it CanHaveServerControls gets false value. Its value is true when Xsl or XslLink is set for XSLV. Is there any possibility to create view with XslLink set for XSLV?

    Regards, Sergey

    ReplyDelete
  68. Hi,
    I haven't checked it directly but looking at the code with reflector it seems that it is possible to do this with setting the XslLink element of the list view in the custom list schema. The only extra thing to add is a "CanHaveServerControl" (note that it is not in the plural, the way I wrote it is not a typo) attribute (not element) with the value "TRUE" of the root "View" element of the list view in the custom schema.
    Let me know if this works for you.

    Greetings
    Stefan

    ReplyDelete
  69. Stefan, thanks a lot,i've tried your approach - but with no success. I've added 'CanHaveServerControl' attribute with TRUE value and define XSLLink view element in custom schema. When i check list view definition after deployment i can't found this attribute at all. It seems the only solution is to use feature event receiver to set xsl link for XSLV using SPLimitedWebPartManager. I suppose that XSLV can only render server controls defined in xsl template when Xsl or XSLLink are set for it. Any thoughts, probably you can propose another approach?

    ReplyDelete
  70. Hi,
    you are right - I tested it myself with a list instance with custom schema and saw that it didn't work. And even if it is possible to hack this using code it wouldn't matter much because you can do that equally easy with the XLV's properties. I may try to dig a bit more into that and if I find a way to do this fully declaratively I will post another comment.

    Greets
    Stefan

    ReplyDelete
  71. Really well written blog!!
    One short question: Where can I "steal" the standard xsl transform used by a view? In order to customize that? Because writing it from scratch just for minor changes would be alot of work...

    Kind regards,
    John

    ReplyDelete
  72. Hi Anonymous,
    The standard XSL file used in the XLV web part is this one: [SP2010 HIVE ROOT]TEMPLATE\LAYOUTS\XSL\main.xsl - it itself includes two other XSL files from the same folder - vwstyles.xsl and fldtypes.xsl (which actually contain most of the transformation logic).
    Basically you can override XSL templates from both the vwstyles.xsl and fldtypes.xsl in your customized "main.xsl" file (you will have some different file name for it).

    Greets
    Stefan

    ReplyDelete
  73. Hi Stefan! Thank you very much for your fast reply...I just added a fldtypes_yourfieldname.xsl for each field which needs special formatting / rendering. This file then contains the xslt transform for the field...

    Kind regards,
    John

    ReplyDelete
  74. This neat feature that the XsltListViewWebPart will call ParseControl if any elements contain runat="server" -- is this only in SharePoint 2010, or does SharePoint 2007 have a way to use this also?

    I ask because in your other article: http://stefan-stanev-sharepoint-blog.blogspot.com/2010/09/xsltlistviewwebpart-contentbyquerywebpa.html

    you said that this feature can be used to put server controls into DataFormWebParts, and SharePoint 2007 does have those.

    - Perry

    ReplyDelete
  75. Hi Anonymous,

    I checked and indeed - this functionality is available in the DataFormWebPart in SP 2007

    Greets
    Stefan

    ReplyDelete
  76. Stefan, thank you for your helpful response.

    I am trying to figure out how to use this technique for WSS 3 OOB server controls. But I am puzzled by the TagPrefix in your example.

    Your example seems to register a tag prefix of "asp", and yet the server control on the next line seems to use a tag prefix of "mycontrols" -- is this a typo, or am I just not understanding correctly?

    I think, if that was a typo, that I would want something like the following:






    - Perry

    ReplyDelete
  77. Oops, the page seems to have chopped out my example. I'll take my example text, html encode it first, and then paste the html-encoded version here:


    <xsl:value-of disable-output-escaping="yes" select="'&lt;%@ Register Tagprefix=&quot;asp&quot; Namespace=&quot;System.Web.UI.WebControls&quot; Assembly=&quot;System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a&quot; %&gt;'"/>

    <asp:TextBox runat="server" Text="hi world" />


    -- Perry

    ReplyDelete
  78. Hi Perry,

    yes, this is a typo, the Tagprefix attribute should be indeed "mycontrols". Btw - I think that it was possible to skip the "Register" directive for the "asp" prefix if you use it for standard System.Web.dll controls

    Greets
    Stefan

    ReplyDelete
  79. Hi stefan,

    Very nice blog!
    We have one problem after migration from sharepoint 2007 to 2010.
    When we are creating a new view and setting the Count for a column in Totals section then the count is not displaying but for the existing views the count is getting displayed.After some RnD we found When creating a new view it is using the old listviewwebpart instead of the new XLSTviewwebpart. With new document libraries and new view its working fine.Any idea?



    ReplyDelete
  80. I am William..I just browsing through some blogs and came across yours! Excellent blog, good to see someone actually uses for quality posts.Your site kept me on for a few minutes unlike the rest :) Keep up the good work!Thanks for sharing a important information on http://www.bigclasses.com/microsoft-sharepoint-online-training.html

    ReplyDelete
  81. Hi Stefan
    Thanks for writing this great post.
    Is the "Register.." tag possible to be used inside XSLT of a data view web part (aka data form web part) also? I need to use controls from Microsoft.SharePoint.Portal.Webcontrols namespace (SP 2010) however I saw only one solution for that on web i.e. extending the DFWP.

    http://www.chaholl.com/archive/2010/01/26/extending-the-dataform-web-part-to-allow-custom-field-controls.aspx

    Is there a way to do this without extending DFWP?
    Would appreciate any suggestions please.

    Thanks,

    ReplyDelete
  82. Hi,

    I am not sure but it seems it's worth giving it a try. I checked the code of the DFWP, it simply puts the "register" directives in the beginning of the transformed XSLT, so if the directives are already there it may work.

    Greetings
    Stefan

    ReplyDelete