2012-05-21 9 views
6

Im trabajando en una plataforma de comercio electrónico que admite múltiples tiendas en diferentes dominios. El backend está completo (por ahora) y ahora estoy comenzando la parte de front-end. Dado que la plataforma es compatible con múltiples tiendas, necesito algún tipo de sistema de plantillas y todavía no he descubierto cuál es la mejor manera de hacerlo.Creación de plantilla de sitio web que es independiente del código fuente en asp.net webforms

Estos son mis requisitos:

  • no quiero reconstruir mi solución a añadir una nueva plantilla
  • Las plantillas se almacenan en/Plantillas/TemplateDirectoryName
  • Quiero ser capaz de utilizar Controles de usuario (predefinidos) dentro de las plantillas.
  • Uso el enrutamiento URL y solo tengo 1 página Default.aspx que controla qué plantilla de página y qué código adicional deben cargarse.

Esto es lo que se me ocurrió hasta el momento:

  • En mi directorio de plantillas tengo plantillas creadas con páginas maestras (Un archivo maestro de página, un archivo maestro predeterminado, y los archivos de sub-maestros que hacen referencia a el archivo maestro por defecto ... para el detalle del producto, navegar, buscar, etc)
  • página
  • Mi Default.aspx recoge la plantilla adecuada de enrutamiento basado en valores

Si bien esta forma de trabajar no creo que es muy práctico pero t Mientras más lo pienso, más llego a la conclusión de que no hay tantas otras opciones para sortear esto. Creo que esto es lo que quiero preguntar: ¿hay alguna manera de utilizar controles de usuario en una plantilla y tener la plantilla completamente separada de la aplicación para que los usuarios puedan crear plantillas sin tener que preocuparse por el espacio de nombres y la estructura del sitio?

Saludos cordiales, Marcar

+0

Pregunta interesante ... Ya me hice esta pregunta en el pasado, pero cambié rápidamente mi enfoque debido a mi falta de conocimiento. +1 para tal vez iluminarme. –

+0

"El backend está completo (por ahora):" Me temo que ha limitado sus elecciones construyendo el back-end ya. Una solución basada en el marco muy probablemente implicaría una reescritura. –

+0

@ArtharAnis - Cuando tenga la oportunidad, dígame qué opina de mi respuesta. – Peter

Respuesta

0

No sé si he entendido bien:

Si no desea reconstruir, entonces yo puedo decir un concepto CMS es la más apropiada para usted.

  • Puede almacenar sus plantillas como un archivo HTML en la base de datos y de la base de datos se puede recuperar de nuevo,
  • le puede dar una funcionalidad de administración con el editor para editar su plantilla en línea también.
2

Como hace referencia a una carpeta para plantillas, ¿no sería posible simplemente cambiar los archivos .aspx en la carpeta y asp.net recogerá la plantilla en función de la ruta de la url que ha mencionado ? Creo que eso es posible en asp.net.
Además, Frameworks como DotNetNuke, Sharepoint, Joomla etc. tienen el mismo concepto. Puede hacer uso de sus características.

1

Mi solución propuesta está a continuación. Tiene algunas limitaciones, como todas las páginas maestras necesitan implementar el mismo conjunto de controles de marcador de posición (lo cual no es sorprendente). Echa un vistazo y cuéntame lo que piensas.

puedo configurar mi estructura de carpetas como esto:

web -> Plantillas -> TemplateFolder (llamado igual que la plantilla)
web -> Plantillas -> UserControls (controles de usuario se almacenan en una plantilla no específica carpeta)

que define una clase simple de configuración de la plantilla, que podemos almacenar/guardar/cargar una plantilla básica deffinition:

public class Template 
{ 
    public string TemplateName { get; set; } 
    public string UserControlName { get; set; } 
    public string MasterPageName { get; set; } 

    public string TemplateFolder 
    { 
     get 
     { 
      return GetTemplateFolder(TemplateName); 
     } 
    } 

    public string TemplateConfigFile { get { return GetTemplateConfigFile(TemplateName); } } 

    private static string GetTemplateFolder(string name) 
    { 
     return HttpContext.Current.Server.MapPath("~/Templates/" + name + "/"); 
    } 

    private static string GetTemplateConfigFile(string name) 
    { 
     return GetTemplateFolder(name) + "/" + name + ".config"; 
    } 

    public Template() 
    { 

    } 

    public void Save() 
    { 
     XmlSerializer xs = new XmlSerializer(typeof(Template)); 

     if (!Directory.Exists(TemplateFolder)) Directory.CreateDirectory(TemplateFolder); 

     using (FileStream fs = File.OpenWrite(TemplateConfigFile)) 
     { 
      xs.Serialize(fs, this); 
     } 
    } 

    public static Template Load(string name) 
    { 
     if(!File.Exists(GetTemplateConfigFile(name))) return null; 

     XmlSerializer xs = new XmlSerializer(typeof(Template)); 

     using (FileStream fs = File.OpenRead(GetTemplateConfigFile(name))) 
     { 
      Template t = (Template)xs.Deserialize(fs); 

      return t; 
     } 
    } 
} 

Se puede construir un cierto código XML desnuda para empezar con ejecutando el código abajo:

Template t1 = new Template() { TemplateName = "Template1", MasterPageName = "Child1.master", UserControlName = "uc1.ascx" }; 
    Template t2 = new Template() { TemplateName = "Template2", MasterPageName = "Child2.master", UserControlName = "uc2.ascx" }; 

    t1.Save(); 
    t2.Save(); 

creé una página básica maestro. Esta página probablemente nunca se use excepto para dar a su página predeterminada los marcadores de posición básicos. Todas sus páginas maestras deben tener el mismo conjunto de marcadores de posición que su base para que sus páginas puedan usarlos todos de manera intercambiable. Observe que dejé un marcador de posición para nuestro control de usuario.

<%@ Master Language="C#" AutoEventWireup="true" CodeFile="BaseMaster.master.cs" Inherits="Templates_Masters_BaseMaster" %> 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head runat="server"> 
    <title></title> 
    <asp:ContentPlaceHolder id="head" runat="server"> 
    </asp:ContentPlaceHolder> 
</head> 
<body> 
    <form id="form1" runat="server"> 
    <div> 
     <asp:ContentPlaceHolder id="cphHeader" runat="server"> 

     </asp:ContentPlaceHolder> 
     <asp:ContentPlaceHolder id="cpUserControl" runat="server"> 

     </asp:ContentPlaceHolder> 
     <asp:ContentPlaceHolder id="cphFooter" runat="server"> 

     </asp:ContentPlaceHolder> 
    </div> 
    </form> 
</body> 
</html> 

Ahora creo una página web aspx básica que utiliza la página maestra anterior.

<%@ Page Title="" Language="C#" MasterPageFile="~/Templates/Masters/BaseMaster.master" AutoEventWireup="true" CodeFile="DefaultTemplated.aspx.cs" Inherits="DefaultTemplated" %> 

<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server"> 
</asp:Content> 
<asp:Content ID="Content2" ContentPlaceHolderID="cphHeader" Runat="Server"> 
</asp:Content> 
<asp:Content ID="Content3" ContentPlaceHolderID="cpUserControl" Runat="Server"> 
</asp:Content> 
<asp:Content ID="Content4" ContentPlaceHolderID="cphFooter" Runat="Server"> 
</asp:Content> 

En el código subyacente vamos a configurar las plantillas básicas. Esto establece la página maestra y agrega un control de usuario predefinido al marcador de posición de contenido para los controles de usuario. Si quisieras, podrías hacer un panel o algo así y agregarlo a ese control fijo, pero pensé que podrías apreciar cómo hacer que funcione con las páginas maestras.

public partial class DefaultTemplated : System.Web.UI.Page 
{ 
    private Template PageTemplate 
    { 
     get 
     { 
      if (_tLoaded == null) 
      { 
       string template = Request.QueryString["template"]; 
       if (string.IsNullOrEmpty(template)) return null; 

       Template t = Template.Load(template); 
       _tLoaded = t; 
      } 

      return _tLoaded; 
     } 
    } 

    private Template _tLoaded = null; 

    protected void Page_Load(object sender, EventArgs e) 
    { 
     if (PageTemplate != null) 
     { 
      //cpUserControl is the name of my usercontrol placeholder 
      ((ContentPlaceHolder)Page.Form.FindControl("cpUserControl")).Controls.Add(
        Page.LoadControl("~/Templates/UserControls/" + PageTemplate.UserControlName)); 
     } 
    } 

    protected void Page_PreInit(object sender, EventArgs e) 
    { 
     if (PageTemplate == null) return; 

     this.MasterPageFile = "~/Templates/" + PageTemplate.TemplateName + "/" + PageTemplate.MasterPageName; 
    } 
} 

Si tuviera una plantilla llamada "Plantilla1" que podría utilizarlo llamando "Default.aspx? Template = Plantilla1". Como está utilizando la reescritura de URL, utilizará la reescritura para pasar el nombre de la plantilla como parámetro a la página.

Otra opción que se podría combinar con lo anterior sería el uso de Page.ParseControl. Utilizando esto, puede almacenar su código de diseñador raw asp.net (solo diseñador) en una base de datos o archivo de texto sin procesar. Posteriormente, se podría crear una instancia que se carga de esta manera:

//where pnl1 is a Panel on the page. Page.ParseControl just returns a control object, so use it anywhere. 
pnl1.Controls.Add(Page.ParseControl("raw asp.net designer code here.")); 

Una gran cosa acerca de esto es que los controles anidados funcionan muy bien también.

Cuestiones relacionadas