2011-10-01 35 views
5

Tengo un cliente que quiere un diseño de página única para su sitio donde el contenido de cada "página" se muestra/oculta mediante JavaScript mientras el usuario navega por el sitio.Diseño de página única con Orchard CMS

No estoy seguro de la mejor manera de abordar esto con Orchard. Una opción sería tener todo el contenido en un elemento de contenido de una sola página, pero luego perderá la capacidad de utilizar las funciones de navegación de Orchard y no podrá dejar que el cliente piense en la administración en términos de páginas.

¿Alguien tiene ideas o experiencias sobre la mejor manera de configurar esto en Orchard CMS?


Así es la solución que usar según el consejo de 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); 
} 

He creado un nuevo módulo con un controlador que contiene el método de acción anteriormente. El método de acción toma un parámetro para la identificación de la parte de contenido. Los objetos _contentManager y _workContextAccessor se están inyectando en el controlador. La vista Layout.Null.cshtml se creó exactamente como Bertrand sugirió.

+0

Ese es un diseño extremadamente extraño que parece ir en contra del SEO y de toda la usabilidad conocida. ¿Qué lo justifica? –

+0

Parece que está desarrollando una aplicación móvil, ¿verdad? jQuery Mobile? –

+0

@BertrandLeRoy: No necesariamente estoy en desacuerdo.Es lo que quiere el cliente (específicamente quieren que implemente esta plantilla: http://udfrance.com/dev/STUDIO8/index_black.html). El sitio es muy ligero en contenido y SEO no es el objetivo principal. – joshb

Respuesta

8

Esto es lo que haría para lograr ese tipo de experiencia muy pulida sin sacrificar SEO, rendimiento del cliente y facilidad de mantenimiento: siga creando el sitio "clásicamente" como un conjunto de páginas, publicaciones de blog, etc., con sus propias URL. Es el diseño de la página de inicio que debería ser diferente y traer los contenidos de esas otras páginas usando llamadas Ajax. Un método que he estado usando para mostrar los mismos contenidos que un elemento de contenido normal, pero de una llamada Ajax (así que sin el cromo alrededor del contenido, sin traer la hoja de estilo, ya está allí, etc.) es tener una acción de un controlador separado que devuelve el contenido en un "diseño nulo":

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

Entonces, tengo un archivo Layout.Null.cshtml en mis puntos de vista que se ve así:

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

Compensación los wrappers eliminan el renderizado de document.cshtml, y la plantilla en sí misma solo está renderizando una zona, Content. Entonces, lo que se renderiza es solo el contenido y nada más. Ideal para inyectar desde una llamada ajax.

¿Le sirve de ayuda?

+0

Eso suena como una gran solución. ¿Dónde va la acción del controlador que devuelve los contenidos en un "diseño nulo"? – joshb

+0

Donde quiera: módulo, tema, no importa. –

+0

Marcar como respuesta? –

2

Siguiendo la línea de la solución de Bertrand, ¿tendría más sentido implementar esto como FilterProvider/IResultFilter? De esta forma, no tenemos que manejar la lógica de recuperación de contenido. El ejemplo que Bertrand proporcionó no parece funcionar para los elementos de contenido de la Lista.

tengo algo como esto en mi módulo que parece funcionar:

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

Hola Rahul, estoy implementando esto para mi proyecto, pero ¿cómo obtengo el contenido de la página de ajax?, Gracias – tuanvt

+0

@tuanvt revisa mi responder – parliament

2

Reutilizando respuesta de Rahul con código añadido para responder a la pregunta de @ tuanvt. Sinceramente, no estoy seguro de cuál es su pregunta, pero si parece que desea acceder a los datos enviados con la solicitud de Ajax. Si es JSON, está enviando set contentType: "application/json" en la solicitud, JSON.stringify(), luego acceda a él en ActionFilter propuesto por Rahul extrayéndolo de la secuencia de solicitud. Espero que ayude de alguna manera.

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