Gestire le risorse con SparkViewEngine
Già nel post precedente ho introdotto SparkViewEngine; in questo voglio mostrare un’interessante feature che apre diversi scenari di mantenibilità e di “servizio”, come nel caso di Dexter che mostrerò più avanti.
Sicuramente ci sarà capitato molto spesso di dover “hostare” le nostre applicazioni all’interno di una virtual directory, e magari di doverle spostare successivamente sulla root di un sito e viceversa: spesso questo risulta scomodo in quanto può comportare alcune modifiche ai percorsi dei file di risorse (immagini, css, javascript, etc). Se proviamo a guardare il lato pratico, un codice html simile a questo:
<link type="text/css" rel="stylesheet" href="/Styles/Site.css" />
non sarebbe più valido nel caso il sito fosse spostato all’interno di una virtual directory, e dovrebbe diventare una cosa del tipo:
<link type="text/css" rel="stylesheet" href="/MyVirtualDirectory/Styles/Site.css" />
Ovviamente il problema è risolvibile sfruttando un helper che effettua il resolve dell’url, con il conseguente svantaggio di aggiungere codice all’interno del markup, rendendo difficile un eventuale refactoring; a questo si aggiunge la perdita in leggibilità del codice html. Un’altra soluzione è far gestire i percorsi delle risorse a Spark (devo dire che lo fa egregiamente e con estrema semplicità) : in primis è necessario modificare il web.config aggiungendo la sezione di Spark, come mostrato di seguito:
<section name="spark" type="Spark.Configuration.SparkSectionHandler, Spark" requirePermission="false"/>
</configSections>
<spark>
<compilation debug="false"/>
<pages automaticEncoding="true">
<namespaces>
<add namespace="System" />
<add namespace="System.Web" />
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="System.Linq" />
</namespaces>
<resources>
<add match="~/Scripts" location="/Resource/Scripts" />
<add match="~/Styles" location="/Resource/Styles" />
<add match="~/Images" location="/Resource/Images" />
<add match="~/Media" location="/Resource/Media" />
</resources>
</pages>
</spark>
Come potete intuire la sezione resource è quella più interessante, e ci permette di specificare dove sono presenti i files delle risorse: quindi, lato view, è sufficiente utilizzare il tilde per indicare il percorso iniziale dell’applicativo, poi ci penserà spark in fase di rendering a sostituirlo con quanto specifica nel file di configurazione.
Se proviamo a renderizzare questo codice html con i settaggi sopra specificati, il rendering finale dovrebbe essere questo:
<link type="text/css" rel="stylesheet" href="~/Styles/Site.css" /> <link type="text/css" rel="stylesheet" href="/Resouce/Styles/Site.css" />
Ovviamente questo può aprire un ulteriore scenario, ossia offrire la possibilità a chi sviluppa la parte html di utilizzare alcune CDN (google, Microsoft, etc) senza doverne conoscere il percorso; di fatto, chi vuole sviluppare una skin per dexter e vuole utilizzare la cdn di Microsoft per jQuery, può semplicemente scrivere questo:
<script src="~/Scripts/CDN/jQueryTools/1.2.2/jquery.tools.min.js" type="text/javascript" language="javascript"></script>
Così facendo si può cambiare in un qualsiasi momento la CDN da utilzzare, o scegliere di hostare il file con la libreria su un proprio server.
Di seguito riporto il blocco di configurazione di spark in dexter, che mostra le varie CDN supportate:
<spark>
<compilation debug="false"/>
<pages automaticEncoding="true">
<namespaces>
<add namespace="System" />
<add namespace="System.Web" />
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="System.Linq" />
<add namespace="Dexter.Web.Site.Models.Blog" />
<add namespace="System.Collections.Generic" />
<add namespace="Dexter.Web.Mvc.Helpers" />
<add namespace="Dexter.Core.Configuration" />
<add namespace="Dexter.Core.Concrete" />
<add namespace="Dexter.Web.Mvc.Controls" />
</namespaces>
<resources>
<add match="~/Scripts/CDN/Microsoft" location="http://ajax.microsoft.com/ajax"/> <!-- http://www.asp.net/ajaxlibrary/cdn.ashx -->
<add match="~/Scripts/CDN/Google" location="http://ajax.googleapis.com/ajax/libs"/> <!-- http://code.google.com/apis/ajaxlibs/documentation/#AjaxLibraries -->
<add match="~/Scripts/CDN/jQueryTools" location="http://cdn.jquerytools.org"/> <!-- http://flowplayer.org/tools/download/index.html -->
<add match="~/Scripts" location="~/Scripts" />
<add match="~/Styles" location="~/Styles" />
<add match="~/Images" location="~/Images" />
<add match="~/Media" location="~/Media" />
</resources>
</pages>
</spark>
Ciauz
The comments for this post are closed.
- There is no TrackBack for this post.
#1 da RoBYCoNTe Monday July 2010 alle 12:17
Scusami Ugo, potrei anche sbagliarmi ma lavorando praticamente ogni giorno con virtual directories, io ho risolto il problema semplicemente impostando il percorso relativo. IIS (Versione 6) ha fatto il resto. Se mi trovo nella directory virtual "demo-app" ed ho una cartella "Content/Css/Template.css", provvedo a lincarla direttamente con src="Content/Css/Template.css".
Questo tipo di gestione (quella che hai descritto in questo articolo) mi è tornato utile in IIS 7 in cui ho avuto seri problemi con gli URL di immagini (non volevano proprio funzionare)!
#2 da Ugo Lattanzi Monday July 2010 alle 12:25
Ciao Roby,
si puoi fare così, e puoi anche risalire al percorso con il ../../etc finchè non arrivi al file.
Ma se poi i trovi a dover spostare i files che fai? cambi tutti i percorsi?
In questo modo cambi solo il config ;)
Inoltre se hai necessità di scalare su una CDN causa traffico, costi etc puoi farlo veramente toccando solo il config di spark.
Lavorando con le altre soluzioni è impossibile senza dover andare a toccare il markup di ogni pagina.
Ciauz
#3 da RoBYCoNTe Monday July 2010 alle 12:45
Emm... GIUSTO! Non avevo preso in considerazione queste possibilità, effettivamente qui i vantaggi diventano "ENORMI". OK Articolo messo tra i preferiti per upgrade di vecchi progetti!
Grazie Ugo!