Does anyone know how to get the full url of a node?
NiceUrl only makes /folder/file.aspx, and NiceUrlFullPath gives me inconsistent results.
For nodes in a folder with another hostname, it gives the correct url. (http://domain.com/folder/file.aspx) For nodes in the same folder (same hostname), it prefixes the url like this: /host-name/folder/file.aspx
The last one fails because there is no document at this location.
Actually NiceUrlFullPath is not meant for adding the http hostname in front of the URL, but to make sure that you're not linking to an alias. You're linking to the full (node)path instead.
Well I think you will need to add some logic then to determin which hostname to prefix the url with, dependi ng on the node's location maybe (could use @Path or some XPath)
So if my node ancestor contains Windpower as the nodeName or whatever you called it you could target it like that OR you may have a unique dataType for each main site node with the different url and target it that way.
Never used it, take a look at the source on codeplex and see what its trying to do or like i said do the logic from where the node is in the tree (easiest way IMHO)
I have been digging deeper, and it turns out that if you enable the configuration "UseDomainPrefixes" and the configuration "HideTopLevelNodeFromPath" and set them both to true, then NiceUrl will not provide you with absolute URLs using the domain names. Instead it will reaturn relative URLs.
This is the structure I have
+ domain .com (here is where the hostheader has been set) + Folder + Page
The configuration options HideTopLevelNodeFromPath will hide the top level, in this case "domain.com", but by doing this it hides the hostheader from the script below.
If you set an additional hostheader, one level lower, like this"domain.com/folder", then it will work again.
I changed it a little to make it work:
Below is the methiod in the XSLT library from Umbraco with my changes.
I want to get the full path for the 'new' canonical link (SEO etc).
So, I want to try this code:
<code>
<xsl:template match="/">
<!-- The fun starts here --> <xsl:variable name="url" select="concat('http://',umbraco.library:RequestServerVariables('HTTP_HOST'))" /> <xsl:variable name="canonicalUrl"> <xsl:value-of select="$url"/><xsl:value-of select="umbraco.library:NiceUrl(./parent::node/@id)"/> </xsl:variable>
<link rel="canonical" href="{$canonicalUrl}" />
</xsl:template>
</code>
But the editor gives me an error:
<error>
Error occured
System.OverflowException: Value was either too large or too small for an Int32. at System.Convert.ToInt32(Double value) at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider) at System.Xml.Xsl.Runtime.XmlQueryRuntime.ChangeTypeXsltArgument(XmlQueryType xmlType, Object value, Type destinationType) at System.Xml.Xsl.Runtime.XmlQueryContext.InvokeXsltLateBoundFunction(String name, String namespaceUri, IList`1[] args) at (XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime, XPathNavigator {urn:schemas-microsoft-com:xslt-debug}current) at Root(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime) at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter writer, Boolean closeWriter) at System.Xml.Xsl.XmlILCommand.Execute(IXPathNavigable contextDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter results) at System.Xml.Xsl.XslCompiledTransform.Transform(IXPathNavigable input, XsltArgumentList arguments, TextWriter results) at umbraco.presentation.webservices.codeEditorSave.SaveXslt(String fileName, String oldName, String fileContents, Boolean ignoreDebugging)
</error>
Anybody an idea what's going on?
I just want the full path to the current page (including http://, domain.com and full path to .aspx)
Why? Because ./parent::node/@id doesn't have a real runtime value when saving the xslt, resulting in a call to umbraco.library:NiceUrl() with a incorrect parameter.
Some way or another you probably want control over which one of the associated host headers to be used as you can associate more than one. A quick somewhat convention-oriented hack is to assign the host name (eg. sitea.com, siteb.com, etc.) you want in your cross domain links to the root node (level 1) name and create your own custom NiceUrl as an XSLT script or XsltExtension function:
public static string NiceUrl(int nodeId) { try { Node currentNode = Node.GetCurrent(); Node targetNode = new Node(nodeId);
How to get the full url of a node
Does anyone know how to get the full url of a node?
NiceUrl only makes /folder/file.aspx, and NiceUrlFullPath gives me inconsistent results.
For nodes in a folder with another hostname, it gives the correct url. (http://domain.com/folder/file.aspx)
For nodes in the same folder (same hostname), it prefixes the url like this: /host-name/folder/file.aspx
The last one fails because there is no document at this location.
Why is NicrUrlFullPath not working correctly, if it isn't give a detailed bug report on codplex with steps to reproduce so it can get fixed then.
Or alterntively you could grap the domain using this
Actually NiceUrlFullPath is not meant for adding the http hostname in front of the URL, but to make sure that you're not linking to an alias. You're linking to the full (node)path instead.
You can see how NiceUrl works here, and NiceUrlFullPath here.
The problem is that some of the nodes are on another website (different hostname).You can see an image of the content section here.
The listing of nodes is in Vest Kran/Pressemeldinger, but some of the nodes are located under WindPower/News.
Vest Kran has the hostname vestkran.3ddesign.no, and Windpower has the hostname windpower.3ddesign.no.
Well I think you will need to add some logic then to determin which hostname to prefix the url with, dependi ng on the node's location maybe (could use @Path or some XPath)
I will try to do that, Warren.
Is there a way to get the hostnames from a node in umbraco?
Do you mean the assigned hostname on a node?
I have not done anything like that before, maybe try this umbraco.library method - http://our.umbraco.org/wiki/reference/umbracolibrary/getcurrentdomains
So if my node ancestor contains Windpower as the nodeName or whatever you called it you could target it like that
OR you may have a unique dataType for each main site node with the different url and target it that way.
It seems like GetCurrentDomains() does not work in XSLT.
Never used it, take a look at the source on codeplex and see what its trying to do or like i said do the logic from where the node is in the tree (easiest way IMHO)
For some reason, NiceUrl returns with the correct subdomain when using the parent's @id.
umbraco.library:NiceUrl(./parent::node/@id) returns http://windpower.3ddesign.no/news.aspx
umbraco.library:NiceUrl(@id) returns /news/locking-the-wind-turbines.aspx
So I ended up writing a concatenation like this:
Is NiceUrl supposed to behave like this?
Hi,
You should change the setting in the umbracoSettings.config file:
<requestHandler>
<!-- this will ensure that urls are unique when running with multiple root nodes -->
<useDomainPrefixes>True</useDomainPrefixes>
Refresh, and you should have absolute URLs with the domain names.
Even with this setting enabled, in Umbraco 305, it is not alwyas working properly.
I have been digging deeper, and it turns out that if you enable the configuration "UseDomainPrefixes" and the configuration "HideTopLevelNodeFromPath" and set them both to true, then NiceUrl will not provide you with absolute URLs using the domain names. Instead it will reaturn relative URLs.
This is the structure I have
+ domain .com (here is where the hostheader has been set)
+ Folder
+ Page
The configuration options HideTopLevelNodeFromPath will hide the top level, in this case "domain.com", but by doing this it hides the hostheader from the script below.
If you set an additional hostheader, one level lower, like this"domain.com/folder", then it will work again.
I changed it a little to make it work:
Below is the methiod in the XSLT library from Umbraco with my changes.
Can anyone verify this and test??
<code>
private static string niceUrlDo(int nodeID, int startNodeDepth)
{
XmlDocument umbracoXML = content.Instance.XmlContent;
bool directoryUrls = GlobalSettings.UseDirectoryUrls;
string baseUrl = GlobalSettings.Path;
baseUrl = baseUrl.Substring(0, baseUrl.LastIndexOf("/"));
bool atDomain = false;
string currentDomain =HttpContext.Current.Request.ServerVariables["SERVER_NAME"].ToLower();//Domain.GetDomainsById(nodeID).ToString();
>>> USEDOMAINPREFIXES should be false
if (!UmbracoSettings.UseDomainPrefixes && Domain.Exists(currentDomain)) {
atDomain = true;
}
// Find path from nodeID
String tempUrl = "";
XmlElement node = umbracoXML.GetElementById(nodeID.ToString());
String[] splitpath = null;
if (node != null)
{
try
{
splitpath =
umbracoXML.GetElementById(nodeID.ToString()).Attributes.GetNamedItem("path").Value.ToString().
Split(",".ToCharArray());
int startNode = startNodeDepth;
// check root nodes for domains
if (UmbracoSettings.UseDomainPrefixes && startNode > 1)
{
if (node.ParentNode.Name.ToLower() == "node")
{
Domain[] domains =
Domain.GetDomainsById(int.Parse(node.ParentNode.Attributes.GetNamedItem("id").Value));
if (
domains.Length > 0)
{
tempUrl =
getUrlByDomain(int.Parse(node.ParentNode.Attributes.GetNamedItem("id").Value), "",
atDomain, currentDomain, true);
}
// test for domains on root nodes, then make the url domain only
}
else if (Domain.GetDomainsById(nodeID).Length > 0)
{
tempUrl = getUrlByDomain(nodeID, "",
false, currentDomain, false);
return tempUrl;
}
}
if (splitpath.Length > startNode)
{
for (int i = startNode; i < splitpath.Length; i++)
{
>>> If hiding the top level, go up one level to find the domain name
if (GlobalSettings.HideTopLevelNodeFromPath && i.Equals(2))
{
tempUrl = getUrlByDomain(int.Parse(splitpath[i-1]), tempUrl, atDomain, currentDomain, false);
i = 2;
}
else {
tempUrl = getUrlByDomain(int.Parse(splitpath[i]), tempUrl, atDomain, currentDomain, false);
}
}
}
else
{
// check the root node for language
tempUrl += getUrlByDomain(nodeID, "", atDomain, currentDomain, false);
}
}
catch (Exception e)
{
HttpContext.Current.Trace.Warn("library.NiceUrl",
string.Format("Error generating nice url for id '{0}'", nodeID), e);
tempUrl = "/" + nodeID;
}
tempUrl = appendUrlExtension(baseUrl, directoryUrls, tempUrl);
}
else
HttpContext.Current.Trace.Warn("niceurl", string.Format("No node found at '{0}'", nodeID));
return tempUrl;
}
</code>
Sorry this is a bit OT, but it is related!
I want to get the full path for the 'new' canonical link (SEO etc).
So, I want to try this code:
<code>
<xsl:template match="/">
<!-- The fun starts here -->
<xsl:variable name="url" select="concat('http://',umbraco.library:RequestServerVariables('HTTP_HOST'))" />
<xsl:variable name="canonicalUrl">
<xsl:value-of select="$url"/><xsl:value-of select="umbraco.library:NiceUrl(./parent::node/@id)"/>
</xsl:variable>
<link rel="canonical" href="{$canonicalUrl}" />
</xsl:template>
</code>
But the editor gives me an error:
<error>
Error occured
System.OverflowException: Value was either too large or too small for an Int32.
at System.Convert.ToInt32(Double value)
at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
at System.Xml.Xsl.Runtime.XmlQueryRuntime.ChangeTypeXsltArgument(XmlQueryType xmlType, Object value, Type destinationType)
at System.Xml.Xsl.Runtime.XmlQueryContext.InvokeXsltLateBoundFunction(String name, String namespaceUri, IList`1[] args)
at (XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime, XPathNavigator {urn:schemas-microsoft-com:xslt-debug}current)
at Root(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime)
at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter writer, Boolean closeWriter)
at System.Xml.Xsl.XmlILCommand.Execute(IXPathNavigable contextDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter results)
at System.Xml.Xsl.XslCompiledTransform.Transform(IXPathNavigable input, XsltArgumentList arguments, TextWriter results)
at umbraco.presentation.webservices.codeEditorSave.SaveXslt(String fileName, String oldName, String fileContents, Boolean ignoreDebugging)
</error>
Anybody an idea what's going on?
I just want the full path to the current page (including http://, domain.com and full path to .aspx)
Thanks
Must surround
with an xsl:if statement as in
Why? Because ./parent::node/@id doesn't have a real runtime value when saving the xslt, resulting in a call to umbraco.library:NiceUrl() with a incorrect parameter.
Hope this helps.
Regards,
/Dirk
@Siko279
I just posted a Canonical URL Xslt Macro here:
http://our.umbraco.org/projects/robotstxt-editor/feedback/3098-Ideas-for-automatic-creating-of-Robottxt-rules
I haven't tested it thoroughly, but it is pretty simple, so I think it'll work, and it works on my site.
/rasb
Guys, that is great.
@Dirk, thanks for that. Understood. Unfortunately, my xslt still didn't do what I hoped it would.
@RasB, cheers. Just what I wanted. Thanks. Works like a charm!
Some way or another you probably want control over which one of the associated host headers to be used as you can associate more than one. A quick somewhat convention-oriented hack is to assign the host name (eg. sitea.com, siteb.com, etc.) you want in your cross domain links to the root node (level 1) name and create your own custom NiceUrl as an XSLT script or XsltExtension function:
What is the lastest way to get this to work? I tried Ove's solution, which saves but when run gives an XSLT parsing error.
is working on a reply...