I have an XSLT file that is looking like it would work better as a .NET usercontrol. I should be able to do everything I need to in .NET, but how do I specify an XML filter? In otherwords, how do I convert this to .NET/C#?
<xsl:if test="$currentPage/ancestor-or-self::* [activeMenu = 'Main' or @id=1672]">
There's several ways to achieve this but I've found the easiest is to use uQuery & uQueryExtensions from uComponents, then you can do things like this:
umbraco.presentation.nodeFactory.Node target = uComponents.Core.uQuery.GetNodesByXPath("$ancestorOrSelf/* [activeMenu = 'Main' or @id=1672]").FirstOrDefault();
To use it just add a reference to uComponents.Core.dll to your project and add using uComponents. Note umbraco.presentation.nodeFactory is deprecated in 4.7 and replaced with umbraco.NodeFactory, but uComponents still uses the old version. Everything still works but you'll just get a warning.
Using the built in Umbraco API there is also umbraco.NodeFactory.Node.GetNodeByXpath("xpath") but I don't believe it supports $currentPage and I find uQuery much more flexible/powerful.
Ok, fixed the error above, need another using. So, is this what I would use to conditionally display this usercontrol only on pages that match the criteria?
using System;
using System.Linq;
using umbraco.presentation.nodeFactory;
using uComponents.Core;
namespace UserControls
{
publicpartialclassgetLogInOut_btn : System.Web.UI.UserControl
{
protectedvoid Page_Load(object sender, EventArgs e)
{
Node target = uQuery.GetNodesByXPath("$ancestorOrSelf/* [activeMenu = 'Lawyers' or @id=1672]").FirstOrDefault();
Node currentPage = uQuery.GetCurrentNode();
if (currentPage.Id == target.Id)
logInOut_button.Visible = true;
}
}
}
Which version of uComponents were you using? $ancestorOrSelf was added in a recent version to replace $parentPage. You could try $currentPage also assuming you're on a published node.
I think $ancestorOrSelf was added after 2.1. There is a 2.2 beta if you want to try that, otherwise try replacing with $currentPage or $parentPage (which will go away in 2.2). I believe the error you are receiving is because $ancestorOrSelf doesn't exist in the version you are using.
I took a quick look - are you perhaps running this usercontrol from a page with no parent, ie a level 1 page? If so there is a bug in 2.1 where you'll get the above error as it looks for a parent page when replacing the xpath variables. It's fixed in 2.2 beta.
Yes, I am using this control sitewide, so it does get used on a level 1 page (home page). So, it looks like I have two of the bugs... the version I am running (an early version of 2.1?) does not support $ancestorOrSelf and does not support level 1.
Not sure about beta, I'm sure it's pretty stable though.
But there are plenty of other ways to do what you want, the GetNodesByXPath method I thought would be easiest since you gave an XSLT example and you were converting from XSLT.
You could also do something like this which should give the same desired result:
using uComponents.Core; using uComponents.Core.uQueryExtensions;
I decided to bite the bullet and install 2.2. So far so good. Now, I just need to know what to do with the node once I get it. How do I use it to decide if I want to show my div? This does not do anything.
Node target = uQuery.GetNodesByXPath("$ancestorOrSelf/* [activeMenu = 'Lawyers' or @id=1672]").FirstOrDefault();
if (target == uQuery.GetCurrentNode()) logInOut_button.Visible = true;
Rich, you've provided another valuable nugget of information after pulling my hair out for two weeks or more. Never before have I seen GetProperty.Value.ToString(). Amazing what that tiny word can provide.
Convert XSLT to .NET Usercontrol
I have an XSLT file that is looking like it would work better as a .NET usercontrol. I should be able to do everything I need to in .NET, but how do I specify an XML filter? In otherwords, how do I convert this to .NET/C#?
Hi Connie,
There's several ways to achieve this but I've found the easiest is to use uQuery & uQueryExtensions from uComponents, then you can do things like this:
or
To use it just add a reference to uComponents.Core.dll to your project and add using uComponents. Note umbraco.presentation.nodeFactory is deprecated in 4.7 and replaced with umbraco.NodeFactory, but uComponents still uses the old version. Everything still works but you'll just get a warning.
Using the built in Umbraco API there is also umbraco.NodeFactory.Node.GetNodeByXpath("xpath") but I don't believe it supports $currentPage and I find uQuery much more flexible/powerful.
Hope this helps,
Tom
I'm getting an error about FirstorDefault. Where can I find some sample code to expand upon this idea?
Ok, fixed the error above, need another using. So, is this what I would use to conditionally display this usercontrol only on pages that match the criteria?
Well, not making much progress: Namespace Manager or XsltContext needed. This query has a prefix, variable, or user-defined function.
Hi,
Which version of uComponents were you using? $ancestorOrSelf was added in a recent version to replace $parentPage. You could try $currentPage also assuming you're on a published node.
-Tom
I'm running version 2.1. Are their later versions? Is my codebehind correct?
I think $ancestorOrSelf was added after 2.1. There is a 2.2 beta if you want to try that, otherwise try replacing with $currentPage or $parentPage (which will go away in 2.2). I believe the error you are receiving is because $ancestorOrSelf doesn't exist in the version you are using.
Still getting an error. All I have in my Page_Load is
and I get Object reference not set to an instance of an object.
Hi Connie,
I took a quick look - are you perhaps running this usercontrol from a page with no parent, ie a level 1 page? If so there is a bug in 2.1 where you'll get the above error as it looks for a parent page when replacing the xpath variables. It's fixed in 2.2 beta.
-Tom
Tom,
Yes, I am using this control sitewide, so it does get used on a level 1 page (home page). So, it looks like I have two of the bugs... the version I am running (an early version of 2.1?) does not support $ancestorOrSelf and does not support level 1.
How long before Beta 2.2 is ready for prime time?
Not sure about beta, I'm sure it's pretty stable though.
But there are plenty of other ways to do what you want, the GetNodesByXPath method I thought would be easiest since you gave an XSLT example and you were converting from XSLT.
You could also do something like this which should give the same desired result:
I decided to bite the bullet and install 2.2. So far so good. Now, I just need to know what to do with the node once I get it. How do I use it to decide if I want to show my div? This does not do anything.
Node target = uQuery.GetNodesByXPath("$ancestorOrSelf/* [activeMenu = 'Lawyers' or @id=1672]").FirstOrDefault();
if (target == uQuery.GetCurrentNode())
logInOut_button.Visible = true;
Something like this
if (target.Count > 0)
{
//grab the first node (hopefully be only node)
var node = target [0];
//Now do something with node
node.GetProperty("YourProperty").Value.ToString();
}
Rich
Rich, you've provided another valuable nugget of information after pulling my hair out for two weeks or more. Never before have I seen GetProperty.Value.ToString(). Amazing what that tiny word can provide.
Ok, problem... there is no Count for target. Oh how I wish there was documentation for all of this so I didn't have to keep bugging.
is working on a reply...