在c#中通过路径获取Umbraco节点(语言切换)

时间:2010-09-24 05:50:58

标签: umbraco

我有一个多语言网站,其结构如下:

siteroot
- en
-- home
-- login
-- etc.
- de
-- home
-- login
-- etc. 

语言节点下的内容不一定相同。 切换语言时,我想测试是否存在并行语言节点。

目前我正在做以下事情:

  • 获取当前路径
  • 替换路径的语言部分 例如replace / en / login to / de / login
  • 我发现最接近测试页面存在的是: XPathNodeIterator i = umbraco.library.GetXmlDocumentByUrl(“http://localhost/de/login”);

调试显示,umbraco实际上是在点击数据库。这不是测试页面存在的最佳方法。

有人手头有更好的方法吗?

2 个答案:

答案 0 :(得分:1)

通过声音使用cms.businesslogic.web命名空间中的文档类。该类用于修改/发布umbraco内的节点。

尝试使用驻留在umbraco.presentation.nodeFactory中的节点类。这将仅与内存中的XML缓存交互。

Node.GetCurrent() //static method - will give you the current loaded page.
Node.Parent //class property - will give parent method

节点类的问题,它不能接受XPath查询(并且不会提供性能)

我编写了一个动态Linq提供程序,可以使用已编译的xslt表达式查询Umbraco XML结构。我将在下周左右发布。如果您有兴趣,请告诉我......

答案 1 :(得分:0)

我们有一个多语言网站,我们需要做同样的事情来设置我们的hreflang标签。可能有更好的方法,但我决定构建一些Xpath来查明其他语言中是否存在匹配的节点。我们正在使用umbraco 7,如果可能的话,我会回避使用NodeFactory。它是折旧的。使用umbraco助手不会访问数据库,这是从umbraco查询umbraco 7的已发布内容或媒体的最佳方式之一。

public static IPublishedContent GetLocalizedVersionOfPage(this IPublishedContent node, string regionName)
{
    var umbracoHelper = new UmbracoHelper(UmbracoContext.Current);
    var ancestorNames = node.AncestorsOrSelf()
                            .Where(n => n.Level > 1)
                            .OrderBy(n => n.Level)
                            .Select(n => n.Name).ToList();

    var xpath = new StringBuilder();
    xpath.AppendFormat("/root/HomePage[@nodeName='{0}']", regionName);
    foreach (var ancestorName in ancestorNames)
    {
        xpath.AppendFormat("/*[@nodeName='{0}']", ancestorName);
    }

    var matchingNode = umbracoHelper.TypedContentAtXPath(xpath.ToString()).FirstOrDefault();
    return matchingNode;
}

上述方法是IPublishedContent的扩展方法。它允许您传入区域,并检查指定区域中是否存在由节点名称确定的具有相同路径的节点。我想过使用urlname而不是节点名。您也可以这样做,甚至可以通过跳过执行.AncestorsOrSelf()的代码来加快速度。这取决于你希望它如何工作。在我的情况下,我希望它找到基于节点名称的匹配,即使url路径不同,所以我必须执行.AncestorsOrSelf()。希望这会有所帮助。

要考虑的另一件事是如何调用此方法。如果你使用这样的循环:

@foreach (var region in Umbraco.TypedContentAtRoot().Where(n => n.IsDocumentType("HomePage")))
{
    var localizedVersion = currentPage.GetLocalizedVersionOfPage(region.Name);
    if (localizedVersion != null)
    {
        <link rel="alternate" href="@localizedVersion.UrlAbsolute()" hreflang="@LocalizeUtils.GetCulture(region.Name)" />
    }
}

您最终会为每个区域反复获取当前节点的祖先一次,因为每次调用.AncestorsOrSelf()时它都会调用GetLocalizedVersionOfPage()。重构GetLocalizedVersionOfPage方法可能是有意义的,因此您只需要调用.AncestorsOrSelf一次。如果你做了太多次这样的事情,它会开始影响性能(特别是如果你的网站非常嵌套)。