Одиночный дизайн страницы с использованием Orchard CMS - PullRequest
5 голосов
/ 01 октября 2011

У меня есть клиент, которому нужен дизайн одной страницы для своего сайта, где содержимое каждой "страницы" отображается / скрывается с использованием javascript, когда пользователь перемещается по сайту.

Я не уверен влучший способ приблизиться к этому, используя сад.Один из вариантов - разместить все содержимое на одном элементе страницы, но тогда вы потеряете возможность использовать навигационные функции Orchard и не сможете позволить клиенту думать об администрировании с точки зрения страниц.

У кого-нибудь есть идеи или опыт, как лучше всего это настроить в Orchard CMS?


Вот решение, которое я использовал, основываясь на совете Бертрана:

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

Я создал новый модульконтроллер, содержащий метод действия выше.Метод действия принимает параметр для идентификатора части содержимого.Объекты _contentManager и _workContextAccessor внедряются в контроллер.Представление Layout.Null.cshtml было создано в точности так, как предложил Бертран.

Ответы [ 3 ]

8 голосов
/ 03 октября 2011

Вот что я хотел бы сделать, чтобы добиться такого безупречного опыта, не жертвуя 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, а сам шаблон отображает только одну зону, Content.Итак, то, что визуализируется, это просто содержимое и ничего больше.Идеально для инъекций из вызова ajax.

Помогает ли это?

2 голосов
/ 20 марта 2013

Повторное использование ответа Рахула с добавленным кодом для ответа на вопрос @ tuanvt.Честно говоря, я не уверен, какой у вас вопрос, но если вам кажется, что вы хотите получить доступ к данным, отправленным с помощью запроса ajax.Если это JSON, вы отправляете set contentType: «application / json» по запросу, JSON.stringify (), затем обращаетесь к нему в предложенном Рахулом 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) {
  }        
}
2 голосов
/ 25 октября 2011

Следуя примеру решения Бертранда, имеет ли смысл реализовывать это как FilterProvider / IResultFilter? Таким образом, нам не нужно обрабатывать логику поиска контента. Пример, который предоставил Бертран, похоже, не работает для элементов содержимого Списка.

У меня есть что-то вроде этого в моем модуле, который, кажется, работает:

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