使用Orchard CMS进行单页面设计

发布于 2024-12-07 16:56:09 字数 752 浏览 0 评论 0原文

我有一个客户想要为他的网站进行单页面设计,其中每个“页面”的内容在用户浏览网站时使用 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);
}

我创建了一个新模块,其中的控制器包含上面的操作方法。该操作方法采用内容部分 ID 的参数。 _contentManager 和 _workContextAccessor 对象被注入到控制器中。 Layout.Null.cshtml 视图的创建与 Bertrand 的建议完全相同。

I have a client who want's a single page design for his site where the content for each "page" is shown/hidden using javascript as the user navigates the site.

I'm not sure on the best way to approach this using Orchard. One option would be to have the content all on a single page content item but then you lose the ability to use the navigation features of Orchard and can't let the client think about administration in terms of pages.

Does anyone have ideas or experiences on how best to set this up in Orchard CMS?


Here's the solution I used based on Bertrand's advice:

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

I created a new module with a controller containing the action method above. The action method takes a parameter for the content part id. The _contentManager and _workContextAccessor objects are being injected into the controller. The Layout.Null.cshtml view was created exactly like Bertrand suggested.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

爱的十字路口 2024-12-14 16:56:09

为了在不牺牲 SEO、客户端性能和可维护性的情况下实现这种非常精致的体验,我会采取以下措施:仍然“经典”地创建网站,作为一组页面、博客文章等,并具有自己的 URL。主页布局应该有所不同,并使用 Ajax 调用引入其他页面的内容。
我一直使用的一种方法是通过 Ajax 调用来显示与常规内容项相同的内容(因此内容周围没有镶边,也没有引入样式表,因为它已经存在了,等等)一个单独的控制器操作,返回“空布局”中的内容:

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 中删除渲染,并且模板本身是仅渲染一区,内容。所以渲染的只是内容,没有其他内容。非常适合从 ajax 调用注入。

这有帮助吗?

Here's what I would do to achieve that sort of very polished experience without sacrificing SEO, client performance and maintainability: still create the site "classically" as a set of pages, blog posts, etc., with their own URLs. It's the home page layout that should then be different and bring the contents of those other pages using Ajax calls.
One method that I've been using to display the same contents as a regular content item, but from an Ajax call (so without the chrome around the content, without bringing the stylesheet in, as it's already there, etc.) is to have a separate controller action that returns the contents in a "null layout":

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

Then, I have a Layout.Null.cshtml file in my views that looks like this:

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

Clearing the wrappers removes the rendering from document.cshtml, and the template itself is only rendering one zone, Content. So what gets rendered is just the contents and nothing else. Ideal to inject from an ajax call.

Does this help?

一张白纸 2024-12-14 16:56:09

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

Following along the lines of Bertrand's solution, would it make more sense to implement this as a FilterProvider/IResultFilter? This way we don't have to handle the content retrieval logic. The example that Bertrand provided doesn't seem to work for List content items.

I've got something like this in my module that seems to work:

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) {
    }        
}
美羊羊 2024-12-14 16:56:09

重用 Rahul 的答案并添加代码来回答 @tuanvt 的问题。老实说,我不确定您的问题是什么,但您似乎想访问通过 ajax 请求发送的数据。如果它是 JSON,则您要在请求中发送 set contentType: "application/json" JSON.stringify() it ,然后通过从请求流中提取它来在 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) {
  }        
}

Reusing Rahul's answer with added code to answer @tuanvt's question. I'm honestly not sure what your question is but if seems like you want to access the data sent with the ajax request. If it's JSON you're sending set contentType: "application/json" on the request, JSON.stringify() it , then access it in Rahul's proposed ActionFilter by extracting it from the request stream. Hope it helps in any way.

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) {
  }        
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文