Orchardcms 使用Orchard CMS的单页设计

Orchardcms 使用Orchard CMS的单页设计,orchardcms,Orchardcms,我有一个客户,他希望为他的站点设计一个页面,在用户导航站点时,使用javascript显示/隐藏每个“页面”的内容 我不确定使用Orchard的最佳方法。一种选择是将所有内容放在一个页面内容项上,但这样您就失去了使用Orchard导航功能的能力,并且不能让客户端考虑页面管理 有没有人对如何最好地在Orchard CMS中设置此功能有想法或经验 以下是我根据Bertrand的建议使用的解决方案: public ActionResult Display(int id) { var con

我有一个客户,他希望为他的站点设计一个页面,在用户导航站点时,使用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方法为content part id获取一个参数。正在将_contentManager和_workContextAccessor对象注入控制器。Layout.Null.cshtml视图的创建与Bertrand的建议完全相同。

以下是在不牺牲搜索引擎优化、客户端性能和可维护性的情况下,我要做的事情,以实现那种非常完美的体验:仍然“经典地”创建一个包含页面、博客帖子等的网站,并使用它们自己的URL。主页布局应该有所不同,并使用Ajax调用提供其他页面的内容。 我一直在使用一种方法来显示与常规内容项相同的内容,但它是通过Ajax调用实现的(因此在内容周围没有chrome,没有引入样式表,因为它已经存在了,等等),就是使用一个单独的控制器操作,以“null布局”返回内容:

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

@{
    Model.Metadata.Wrappers.Clear();
}
@Display(Model.Content)
清除包装器将从document.cshtml中删除呈现,模板本身仅呈现一个区域,即内容。所以呈现的只是内容,而不是其他。非常适合从ajax调用进行注入


这有帮助吗?

按照Bertrand的解决方案,将其作为FilterProvider/IResultFilter实现是否更有意义?这样我们就不必处理内容检索逻辑。Bertrand提供的示例似乎不适用于列表内容项

我在我的模块中有类似的东西,似乎可以工作:

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) {
    }        
}

通过添加代码重用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) {
  }        
}

这是一个极其怪异的设计,似乎与SEO和所有已知的可用性背道而驰。有什么理由?看起来你正在开发一款移动应用,对吗?jQuery Mobile?@BertrandLeRoy:我不一定不同意。这是客户想要的(特别是他们希望我实现这个模板:)。该网站内容非常简单,SEO不是主要目的。@pszmyd:不是jquery移动应用程序,而是类似的用例。没有返回_contentmanager的结果。暴露一个安全漏洞,因为据我所知,所有管理数据都可以使用content manager检索?只需尝试id的各种值,直到您返回用户帐户信息或其他特权数据。这听起来是一个很好的解决方案。在“空布局”中返回内容的控制器操作去哪里了?你想去哪里:模块,主题,没关系。谢谢Bertrand。我试试看。我不知道该怎么做,但希望当我进入其中并完成它时,它会更清晰。如果更简单的话,你也可以从处理程序中添加备用代码。我添加了一个模块(使用codegen),并在我的控制器操作中添加了你的第一个代码块。但是,我不清楚workContextAccessor和shape对象来自哪里。你能给我一些指导吗?谢谢Shello Rahul,我正在为我的项目实现这个功能,但是如何从ajax中获取页面内容呢?谢谢
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) {
  }        
}