Contents tagged with SharePoint
SharePoint offers a couple of ways by which we can obtain the current user for use in a XSLT web part like DataFormWebPart or XsltListViewWebPart. All involve first setting parameters through the ParameterBindings property:
Here we see different kinds of parameters:
- CAMLVariable: built in variables UserID and Today;
- WPVariable: returns one of the predefined values for _WPID_ (web part client id), _WPQ_ (web part unique id in page), _WPR_ (web part resources folder full URL), _WPSRR_ (web part resources folder relative URL), _LogonUser_ (server variable LOGON_USER), _WebLocaleId_ (current site locale, as in CultureInfo.LCID);
- ServerVariable: returns one of the HTTP or IIS server- defined variables.
This will return something like this:
UserID: Ricardo Peres
The ddwrt:UserLookup extension function returns a value depending on the second parameter; valid values are Id, Email and Login, and you can easily guess what they are for.
You can find a reference for LOGON_USER, AUTH_USER, REMOTE_USER and UNMAPPED_REMOTE_USER here. In my development server, I get the same value for all variables.
By the way, I posted a more advanced solution, which allows access to any profile properties. You can read it here.
I have already shown how you can display all attributes and their values from a XSLT content, but in case you want to look at the whole structure plus their attributes, you can use this instead:
SharePoint relies on ASP.NET Site Map Providers for generating navigation links on its default pages. Specifically, the default Web.config file registers a (big!) number of providers, which control different aspects of its navigation:
For example, let’s pick one of the providers, SPNavigationProvider, which is registered, appropriately, as SPNavigationProvider. This one is capable of returning the global navigation (Global Navigation) and the quick links (Current Navigation). In order to select one or the other, we supply a special key to its StartingNodeUrl property:
- sid:1000: Home Page;
- sid:1002: Global Navigation;
- sid:1025: Current Navigation;
- sid:1040: Search.
In case you are wondering, these values are defined in the public properties of the SPNavigation class.
This example will list all attributes of all the nodes:
You can see that the SiteMapDataSource returns XML in the form:
Attributes are mostly self-explanatory, but Name and Value have the same content and Description always appears to be empty. For subsites, the NavigateUrl attribute will end in a /. Depending on the provider, it is possible to have nested NavigateUIData nodes.
If you set the ShowStartingNode property to true, you will also get a root node containing the name (for sid:1000 it is Home, for sid:1002 it is SharePoint Top Navigation Bar, for sid:1025 it is Quick Launch and for sid:1040 it is Search) and URL of the current site
Unfortunately, there isn’t much documentation (read: none) about these providers, except, of course, their methods and properties, so you have to figure out yourself. One thing that can be useful is this XSLT that will give you all the nodes and their attributes:
A common request is to be able to retrieve user information from XSLT (XsltListViewWebPart, DataFormWebPart, etc). It is possible to obtain some information through server variables (LOGON_USER), CAML variables (UserID) or ddwrt:UserLookup extension function. It works, to some extent, but sometimes it is not enough.
It is well known that one can have server controls in XSLT stylesheets. As it happens, the ProfilePropertyValue control retrieves any value from the user profile. It just needs to have a ProfilePropertyLoader declared before it, which can be placed in the master page. For example:
Just remember to register the Microsoft.SharePoint.Portal.WebControls assembly with the SPSWC tag prefix, either in the Web.config or in the page itself.
But, what about XSLT? Well, if the SPSWC tag prefix is registered in Web.config, we can do this:
With this technique, you can retrieve any of the profile properties. Ah, don’t forget to add:
To the <xsl:stylesheet> declaration.
Picking on my previous post, I am going to show how you can access SharePoint (and ASP.NET context) from XSLT.
Create a class like this one:
Follow the process described in my post to register it, apply tag mappings and register the controls as safe. Then, on the XSLT, you can access any properties (and properties of properties) of both HttpContext.Current and SPContext.Current instances! The only thing you can’t do is call methods. This is a limitation of DataBinder.Eval.
Notice that when you are to evaluate expressions with “, you must do it in two steps:
- Define a variable that takes the expression;
- In that variable, replace “ for ".
Hope you find it useful!
So, you want to know which fields your data source is returning. You can use the following XSLT:
Very handy, even if I say so myself!
Update: this can also be useful.
Wouldn’t it be good if SharePoint would allow the registration of custom functions that could be used in XSLT stylesheets? Well, as it happens, it does!
Some of the classes that allow XSLT processing – DataFormWebPart, ContentByQueryWebPart - have a virtual method called ModifyXsltArgumentList that can be used for registering custom functions. Sadly, XsltListViewWebPart, XlstListFormWebPart, among others, are sealed, and thus do not allow this.
Let’s forget about the MyFunctions class and pretend that it has a few public instance methods that we want to expose to SharePoint. Mind you, because this class will be instantiated in a SharePoint context, it will have access to SPContext.Current, and from here, to the whole of SharePoint!
In a XSLT script, we need something like this in order to access our extension functions:
Did you notice xmlns:my=”urn:MyFunctions”? This should be identical to the namespace that you used inside ModifyXsltArgumentList.
And to call one of the functions:
Again, you need to use the same prefix, my in this case. You can add parameters, as long as they are of base types (strings, number, date/time, booleans, and so on), and the same goes for the result type.
I hear you say: “OK, but now I have to replace all declarations of DataFormWebPart for this new CustomDataFormWebPart!”. Not really, dear reader, ASP.NET offers a great solution for this: tag mapping. In a nutshell, we can ask ASP.NET to replace all instances of a control for another class that inherits from the control’s class.
Now, we could this in several ways, but the best one is to have a feature targeting a WebApplication with a feature receiver that performs a Web.config modification:
When this feature is activated, it adds a line in the Web.config file, tagMapping section, that tells ASP.NET to replace DataFormWebPart for CustomDataFormWebPart in all markup declarations. Of course, it won’t affect code: new DataFormWebPart() will still return a DataFormWebPart!
All is not done, yet. We still need to mark our CustomDataFormWebPart control as safe for declaration in web pages. We do that by adding an entry to the SafeControls section of the Web.config. For a change, I’m going to do this in the SharePoint Solution Manifest, Package.xml:
Notice the $SharePoint.Project.AssemblyFileName$ and $SharePoint.Project.AssemblyFullName$, these are two examples of tokens that will be replaced by Visual Studio when it deploys the solution.
And that’s it! Your custom XSLT extension functions are ready to use!
Besides the classic ASP.NET data source controls, SharePoint brings along its own. These allow us to retrieve data not just from SharePoint, but also from external sources, such as web services or SQL databases. Using SharePoint Designer you end up using these data sources without even knowing, and, specially, ignoring what other options you have. Let’s look at these controls one by one and see how the can be used. I already talked about the SPDataSource and AggregateDataSource, so I won’t cover these here. I also won’t be covering them in depth, but instead will provide an example of how to use them.
A simple example is:
A BdcDataSource let’s you retrieve data from a BCS data source (external content type). This may happen when you don’t have an external list created or you want to call a specific finder method. You need to specify the namespace, LOB instance, entity, and finder method. If the finder needs parameters, you will need to supply them. It can be customized by hosting it in a DataFormWebPart and by applying XSLT.
Here’s an example:
SoapDataSource is the control that retrieves data from a SOAP web service. You specify the URL of the web service, the action to call and the SOAP envelope, together with any required parameters. It should be hosted in a DataFormWebPart and can thus use XSLT for the formatting of its contents.
An example of calling the Lists.asmx web service:
XsltListViewWebPart (External List)
External lists can be displayed using the XsltListViewWebPart. Nothing really new here.
A simple example (of course, do replace the list and view GUIDs):
The XmlUrlDataSource is used for invoking REST web services. Similar to SoapDataSource, you need to pass it the URL, but also the HTTP method and any parameters. I is also usually hosted in a DataFormWebPart.
Here’s an example of calling the weather service I talked about in another post:
The SPSqlDataSource is what SharePoint uses to access a SQL database. If you use SharePoint Designer to add one such data source, you might be surprised to see that it places a SqlDataSource instead. The thing is, SharePoint uses ASP.NET tag mapping to replace any SqlDataSource control for a SPSqlDataSource. Again, we host it inside a DataFormWebPart for easily formatting its contents and you can pass parameters to the SQL.
An example of the markup:
While SPDataSource is generally the most generic and useful control, it cannot do everything, namely, access external sources. For that, we have other options; the AggregateDataSource can be used to bring together data from all of these sources, except SPHierarchyDataSourceControl and SPCalendarDataSource, but you can easily replace these by SPDataSource.
Let me know if you have any questions!
I know there are dozens out there, but I decided to publish my own field reference for SharePoint. Besides the usual attributes, I include some others, like the SharePoint and CLR type, the enumeration where it is declared (if any), the control used to render it and some more.
Another post that could be subtitled “How to do Things in SharePoint By Hand”. This time, combining data sources – lists, in this case, but the same can be applied to other source types, such as SOAP (SoapDataSource) or REST (XmlUrlDataSource) web services, hierarchies of sites (SPHierarchyDataSourceControl), calendar (SPCalendarDataSource), XML files (SPXmlDataSource), BCS external lists (BdcDataSource) or even SQL queries (SPSqlDataSource).
Enough talk, here is the code:
If you specify the SeparateRoot parameter as true, in the XSL section, you will get two data sources, one for each data source specified as a concat/datasource entry, you will have to access them separately, using syntax /dsQueryResponse/Tasks/Rows/Row, of course, replacing Tasks for the right name, as specified in the concat/datasource’s name attribute;
If you don’t specify a value for SeparateRoot, the default is false, which means that the values for both data sources will come together in /dsQueryResponse/Rows/Row; you can sort out what records belong to one list or the other using the syntax /dsQueryResponse/Rows[@agg:source='Pages']/Row; this is made possible by the xmlns:agg="http://schemas.microsoft.com/sharepoint/aggregatesource" entry in the xsl:stylesheet declaration, which I’m sure you hadn’t noticed ;
In the XSLT, I am iterating through the first list, and for each item, I get one field value (Author = Creation User) and use it to filter the second list. This is the same that SharePoint Designer does when you insert a linked list data source.
And that’s it. Enjoy!