使用Orchard CMS的单页设计

时间:2011-10-01 15:27:51

标签: orchardcms

我有一个客户想要为他的网站设计单页,每个“页面”的内容在用户导航网站时使用javascript显示/隐藏。

我不确定使用Orchard来解决这个问题的最佳方法。一种选择是将内容全部放在单个页面内容项上,但是您失去了使用Orchard导航功能的能力,并且无法让客户考虑页面方面的管理。

有没有人有关于如何在Orchard CMS中进行最佳设置的想法或经验?


以下是我根据Bertrand的建议使用的解决方案:

public ActionResult Display(int id)
{
     var contentItem = _contentManager.Get(id, VersionOptions.Published);
     dynamic model = _contentManager.BuildDisplay(contentItem);
     var ctx = _workContextAccessor.GetContext();
     ctx.Layout.Metadata.Alternates.Add("Layout_Null");
     return new ShapeResult(this, model);
}

我使用包含上述操作方法的控制器创建了一个新模块。 action方法获取内容部分id的参数。 _contentManager和_workContextAccessor对象正在注入控制器。 Layout.Null.cshtml视图的创建与Bertrand建议的完全一样。

3 个答案:

答案 0 :(得分:8)

在不牺牲搜索引擎优化,客户端性能和可维护性的情况下,我将采取以下措施来实现这种非常完美的体验:仍然将网站“经典地”创建为一组页面,博客文章等,并使用自己的URL。这是主页布局应该是不同的,并使用Ajax调用带来其他页面的内容。 我一直用来显示与常规内容项相同内容的一种方法,但是来自Ajax调用(所以没有内容的chrome,没有带样式表,因为它已经存在,等等)是一个单独的控制器动作,以“空布局”返回内容:

var ctx = _workContextAccessor.GetContext();
ctx.Layout.Metadata.Alternates.Add("Layout_Null");
return new ShapeResult(this, shape);

然后,我的视图中有一个Layout.Null.cshtml文件,如下所示:

@{
    Model.Metadata.Wrappers.Clear();
}
@Display(Model.Content)

清除包装器会从document.cshtml中删除呈现,而模板本身只会呈现一个区域Content。所以渲染的只是内容而不是其他内容。非常适合从ajax调用注入。

这有帮助吗?

答案 1 :(得分:2)

遵循Bertrand的解决方案,将它作为FilterProvider / IResultFilter实现更有意义吗?这样我们就不必处​​理内容检索逻辑。 Bertrand提供的示例似乎不适用于List内容项。

我的模块中有类似的东西似乎有效:

public class LayoutFilter : FilterProvider, IResultFilter {
    private readonly IWorkContextAccessor _wca;

    public LayoutFilter(IWorkContextAccessor wca) {
        _wca = wca;
    }

    public void OnResultExecuting(ResultExecutingContext filterContext) {
        var workContext = _wca.GetContext();
        var routeValues = filterContext.RouteData.Values;

        if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest()) {
            workContext.Layout.Metadata.Alternates.Add("Layout_Null");

        }           
    }

    public void OnResultExecuted(ResultExecutedContext filterContext) {
    }        
}

答案 2 :(得分:2)

重复使用Rahul的答案并添加代码来回答@ tuanvt的问题。老实说,我不确定你的问题是什么,但似乎你想要访问使用ajax请求发送的数据。如果它是JSON,你在请求​​上发送set contentType:“application / json”,JSON.stringify()它,然后通过从请求流中提取它来在Rahul提议的ActionFilter中访问它。希望它能以任何方式帮助。

public class LayoutFilter : FilterProvider, IResultFilter {
  private readonly IWorkContextAccessor _wca;

  public LayoutFilter(IWorkContextAccessor wca) {
        _wca = wca;
  }

  public void OnResultExecuting(ResultExecutingContext filterContext) {
      var workContext = _wca.GetContext();
      var routeValues = filterContext.RouteData.Values;

      if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest()) {
           workContext.Layout.Metadata.Alternates.Add("Layout_Null");

           if (filterContext.HttpContext.Request.ContentType.ToLower().Contains("application/json"))
           {
                var bytes = new byte[filterContext.HttpContext.Request.InputStream.Length];
               filterContext.HttpContext.Request.InputStream.Read(bytes, 0, bytes.Length);
               filterContext.HttpContext.Request.InputStream.Position = 0;
               var json = Encoding.UTF8.GetString(bytes);
               var jsonObject = JObject.Parse(json);
               // access jsonObject data from ajax request
           }
      }           
  }

  public void OnResultExecuted(ResultExecutedContext filterContext) {
  }        
}