根级别的 Umbraco 和动态 URL 内容
Umbraco and dynamic URL content at root level
我需要将网站移植到 asp.net 并决定使用 Umbraco 作为底层 CMS。
我遇到的问题是我需要保留当前站点的 URL 结构。
当前 URL 模板如下所示
domain.com/{brand}/{product}
这很难制定路线,因为它与网站上的所有其他内容混合在一起。喜欢 domain.com/foo/bar
不是品牌或产品。
我编写了一个 IContentFinder
,并将其注入 Umbraco 管道,检查 URL 结构并确定 domain.com/{brand}
是否与站点,在这种情况下,我通过其内部路由 domain.com/products/
找到内容,并使用 IContentFinder
.[=21 将 {brand}/{model}
作为 HttpContext Items
和 return 传递=]
这有效,但这也意味着没有调用 MVC 控制器。所以现在我只剩下从 cshtml 文件中的数据库中获取数据,这不是很漂亮并且有点破坏 MVC 约定。
我真正想要的是将 url domain.com/{brand}/{product}
重写为 domain.com/products/{brand}/{product}
然后能够根据参数点击提供内容的 ProductsController品牌和产品。
有几种方法可以做到这一点。
这在一定程度上取决于您的内容设置。如果您的产品在 Umbraco 中作为页面存在,那么我认为您走对了路。
在您的内容查找器中,记得像这样设置您在请求中找到的页面 request.PublishedContent = content;
然后您可以利用 Route Hijacking 添加一个 ProductController,它将为该请求调用:https://our.umbraco.org/Documentation/Reference/Routing/custom-controllers
示例实现:
protected bool TryFindContent(PublishedContentRequest docReq, string docType)
{
var segments = docReq.Uri.GetAbsolutePathDecoded().Split(new[] {'/'}, StringSplitOptions.RemoveEmptyEntries);
string[] exceptLast = segments.Take(segments.Length - 1).ToArray();
string toMatch = string.Format("/{0}", string.Join("/", exceptLast));
var found = docReq.RoutingContext.UmbracoContext.ContentCache.GetByRoute(toMatch);
if (found != null && found.DocumentTypeAlias == docType)
{
docReq.PublishedContent = found;
return true;
}
return false;
}
public class ProductContentFinder : DoctypeContentFinderBase
{
public override bool TryFindContent(PublishedContentRequest contentRequest)
{
// The "productPage" here is the alias of your documenttype
return TryFindContent(contentRequest, "productPage");
}
}
public class ProductPageController : RenderMvcController {}
在示例中,文档类型的别名是 "productPage"。这意味着控制器需要准确命名 "ProductPageController" 并继承 RenderMvcController.
请注意,实际页面名称是什么并不重要。
我需要将网站移植到 asp.net 并决定使用 Umbraco 作为底层 CMS。
我遇到的问题是我需要保留当前站点的 URL 结构。
当前 URL 模板如下所示
domain.com/{brand}/{product}
这很难制定路线,因为它与网站上的所有其他内容混合在一起。喜欢 domain.com/foo/bar
不是品牌或产品。
我编写了一个 IContentFinder
,并将其注入 Umbraco 管道,检查 URL 结构并确定 domain.com/{brand}
是否与站点,在这种情况下,我通过其内部路由 domain.com/products/
找到内容,并使用 IContentFinder
.[=21 将 {brand}/{model}
作为 HttpContext Items
和 return 传递=]
这有效,但这也意味着没有调用 MVC 控制器。所以现在我只剩下从 cshtml 文件中的数据库中获取数据,这不是很漂亮并且有点破坏 MVC 约定。
我真正想要的是将 url domain.com/{brand}/{product}
重写为 domain.com/products/{brand}/{product}
然后能够根据参数点击提供内容的 ProductsController品牌和产品。
有几种方法可以做到这一点。
这在一定程度上取决于您的内容设置。如果您的产品在 Umbraco 中作为页面存在,那么我认为您走对了路。
在您的内容查找器中,记得像这样设置您在请求中找到的页面 request.PublishedContent = content;
然后您可以利用 Route Hijacking 添加一个 ProductController,它将为该请求调用:https://our.umbraco.org/Documentation/Reference/Routing/custom-controllers
示例实现:
protected bool TryFindContent(PublishedContentRequest docReq, string docType)
{
var segments = docReq.Uri.GetAbsolutePathDecoded().Split(new[] {'/'}, StringSplitOptions.RemoveEmptyEntries);
string[] exceptLast = segments.Take(segments.Length - 1).ToArray();
string toMatch = string.Format("/{0}", string.Join("/", exceptLast));
var found = docReq.RoutingContext.UmbracoContext.ContentCache.GetByRoute(toMatch);
if (found != null && found.DocumentTypeAlias == docType)
{
docReq.PublishedContent = found;
return true;
}
return false;
}
public class ProductContentFinder : DoctypeContentFinderBase
{
public override bool TryFindContent(PublishedContentRequest contentRequest)
{
// The "productPage" here is the alias of your documenttype
return TryFindContent(contentRequest, "productPage");
}
}
public class ProductPageController : RenderMvcController {}
在示例中,文档类型的别名是 "productPage"。这意味着控制器需要准确命名 "ProductPageController" 并继承 RenderMvcController.
请注意,实际页面名称是什么并不重要。