2011-10-01 14 views
5

Ho un cliente che desidera un design a pagina singola per il suo sito in cui il contenuto di ogni "pagina" viene visualizzato/nascosto utilizzando javascript mentre l'utente naviga nel sito.Design a pagina singola con Orchard CMS

Non sono sicuro sul modo migliore per avvicinarsi a questo utilizzando Orchard. Un'opzione sarebbe quella di avere il contenuto tutto su un singolo contenuto di una pagina, ma poi si perde la possibilità di utilizzare le funzionalità di navigazione di Orchard e non si può lasciare che il cliente pensi all'amministrazione in termini di pagine.

Qualcuno ha idee o esperienze sul modo migliore di configurarlo in Orchard CMS?


Ecco la soluzione che ho usato sulla base del parere di 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); 
} 

ho creato un nuovo modulo con un controller che contiene il metodo di azione di cui sopra. Il metodo action accetta un parametro per l'id parte contenuto. Gli oggetti _contentManager e _workContextAccessor vengono iniettati nel controller. La vista Layout.Null.cshtml è stata creata esattamente come suggerito da Bertrand.

+0

Questo è un design estremamente bizzarro che sembra volare in faccia alla SEO e a tutta l'usabilità conosciuta. Cosa lo giustifica? –

+0

Sembra che tu stia sviluppando un'app mobile, giusto? jQuery Mobile? –

+0

@BertrandLeRoy: non necessariamente non sono d'accordo.È ciò che vuole il cliente (in particolare mi chiedono di implementare questo modello: http://udfrance.com/dev/STUDIO8/index_black.html). Il sito è molto leggero sul contenuto e SEO non è lo scopo principale. – joshb

risposta

8

Ecco cosa farei per ottenere quel tipo di esperienza molto lucida senza sacrificare SEO, prestazioni del client e manutenibilità: creare ancora il sito "classicamente" come un insieme di pagine, post di blog, ecc. Con i propri URL. È il layout della pagina iniziale che dovrebbe quindi essere diverso e portare il contenuto di quelle altre pagine usando le chiamate Ajax. Un metodo che ho utilizzato per visualizzare gli stessi contenuti di un normale oggetto di contenuto, ma da una chiamata Ajax (quindi senza il cromo attorno al contenuto, senza inserire il foglio di stile, poiché è già lì, ecc.) È avere un'azione di controllo separato che restituisce il contenuto in un "layout di null":

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

Poi, ho un file di Layout.Null.cshtml nel mio punto di vista che assomiglia a questo:

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

Clearing i wrapper rimuovono il rendering da document.cshtml e il modello stesso esegue solo il rendering di una zona, Content. Quindi ciò che viene reso è solo il contenuto e nient'altro. Ideale per iniettare da una chiamata Ajax.

fa questo aiuto?

+0

Sembra un'ottima soluzione. Dove va l'azione del controller che restituisce il contenuto in un "layout nullo"? – joshb

+0

Dove vuoi: modulo, tema, non importa. –

+0

Contrassegna come risposta? –

2

Seguendo le linee della soluzione di Bertrand, avrebbe più senso implementarlo come FilterProvider/IResultFilter? In questo modo non dobbiamo gestire la logica di recupero dei contenuti. L'esempio fornito da Bertrand non sembra funzionare per gli elementi di contenuto Elenco.

ho qualcosa come questo nel mio modulo che sembra funzionare:

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

Ciao Rahul, sto implementando questo per il mio progetto, ma come ottengo il contenuto della pagina da ajax?, Grazie – tuanvt

+0

@tuanvt controlla il mio risposta – parliament

2

Riusare risposta di Rahul con codice aggiunto per rispondere alla domanda di @ tuanvt. Onestamente non sono sicuro di quale sia la tua domanda, ma se sembra che tu voglia accedere ai dati inviati con la richiesta Ajax. Se è JSON stai inviando set contentType: "application/json" sulla richiesta, JSON.stringify() it, quindi accedi ad ActionFilter di Rahul proposto estraendolo dal flusso di richiesta. Spero che aiuti in qualsiasi modo.

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