Zootropo

Diario del mundo geek.

domingo, junio 20, 2004

There is only XUL (IX)

A la hora de organizar los ficheros de nuestra aplicación se sigue un estándar de facto en el que tenemos tres subdirectorios dentro de la carpeta de nuestra aplicación: content, local y skin.

El directorio content incluye un subdirectorio con el nombre de nuestra aplicación que a su vez contiene todos los archivos xul de la aplicación, además de los archivos js con el código javascript de la aplicación y un fichero contents.rdf que nos dice entre otras cosas cual es el archivo .xul principal.

En el directorio locale se incluyen una serie de subdirectorios con el código del idioma correspondiente, por ejemplo es-ES para castellano o en-US para inglés de estados unidos. Dentro de cada uno de estos directorios tenemos un subdirectorio con el nombre de la aplicación que incluye a su vez los ficheros dtd que sirven para separar la aplicación de los mensajes de esta para facilitar el proceso de traducción y un fichero contents.rdf.

Por último el directorio skin contiene otro subdirectorio de nombre classic que incluye un directorio con el nombre de nuestra aplicación con los ficheros css que se utilizan para modificar el aspecto de la aplicación y un archivo contents.rdf.

Hasta ahora el código javascript que hemos utilizado estaba incrustado dentro de los ficheros xul, en el siguiente ejemplo veremos como importar el código de un fichero js separado del código xul. Como simple comentario, el código css que hemos utilizado hasta ahora estaba almacenado en archivos css aparte como dicta la norma para conseguir modularidad; sin embargo, al igual que el código javascript, el código css puede almacenarse en un fichero aparte o incrustado dentro del propio archivo xul.

<?xml version="1.0"?>
<!DOCTYPE window SYSTEM "chrome://caffeine/locale/caffeine.dtd">

<?xml-stylesheet href="chrome://caffeine/skin/caffeine.css" type="text/css"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/ there.is.only.xul"
xmlns:nc="http://home.netscape.com/NC-rdf#">

<script type="application/x-javascript"
src="chrome://caffeine/content/caffeine.js"/>

<button onclick="funcion();" label="&nombreBoton;" accesskey="&teclaAcceso"/>

</window>

La línea de script es la que se encarga de importar el código javascript desde el fichero javascript especificado de forma que podemos usar la función funcion() al hacer click en el botón aunque no la hallamos definido en este fichero. Podemos ver también la forma en que se importan los ficheros dtd con los mensajes de la aplicación en la segunda línea del código fuente. Hasta ahora no habíamos utilizado ficheros dtd, sino que incluíamos el texto de la aplicación imbuida dentro de esta; ahora con estos ficheros llevamos la modularidad de xul hasta el extremo, separando del código xul el funcionamiento, la apariencia y los mensajes.

El uso de los mensajes que se definen en los DTDs podemos verlo en el label y la accesskey del botón, un símbolo ampersand, el nombre que le dimos al mensaje en el dtd y punto y coma. El fichero DTD para este programa sería:

<!ENTITY nombreBoton "Mi Boton">
<!ENTITY teclaAcceso "M">

Para cada mensaje como vemos tenemos un !ENTITY, la segunda entrada de !ENTITY es el nombre del mensaje que se utilizará para referirse a él en el código XUL como ya vimos y el tercero el valor. En este DTD nombreBoton es "Mi Boton" pero podríamos tener otro DTD para el inglés en cuyo caso sería "My Button", etc, de forma que la traducción de la aplicación es mas sencilla al separar el código y los mensajes.

Por último como ya dijimos cada uno de los directorios de la aplicación incluye un fichero contents.rdf para poder registrar ese directorio en el registro chrome. Veamos el caso del contents.rdf de los locales:

<?xml version="1.0"?>
<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:chrome="http://www.mozilla.org/rdf/chrome#">

<!-- Lista de todos los locales que incluimos, en este caso solo es-ES -->
<RDF:Seq about="urn:mozilla:locale:root">
<RDF:li resource="urn:mozilla:locale:es-ES"/>
</RDF:Seq>

<!-- Informacion sobre cada uno de los locales -->
<RDF:Description about="urn:mozilla:locale:es-ES"
chrome:displayName="Castellano (ES)"
chrome:name="es-ES">
<chrome:packages>
<RDF:Seq about="urn:mozilla:locale:es-ES:packages">
<RDF:li resource="urn:mozilla:locale:es-ES:caffeine"/>
</RDF:Seq>
</chrome:packages>
</RDF:Description>

</RDF:RDF>
Y el contents.rdf de los skins:
<?xml version="1.0"?>

<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:chrome="http://www.mozilla.org/rdf/chrome#">

<RDF:Seq about="urn:mozilla:skin:root">
<RDF:li resource="urn:mozilla:skin:classic/1.0" />
</RDF:Seq>

<RDF:Description about="urn:mozilla:skin:classic/1.0">
<chrome:packages>
<RDF:Seq about="urn:mozilla:skin:classic/1.0:packages">

</RDF:Seq>
</chrome:packages>
</RDF:Description>

</RDF:RDF>

Estos dos contents.rdf no necesitan comentarios. Son muy parecidos al contents.rdf del directorio contents. Tan solo queda registrar en el registro chrome contents, locals y skins. Si recordamos en el anterior post sobre XUL al registrar el contents añadíamos a installed-chrome.txt una línea similar a esta:

content,install,url,resource:/chrome/caffeine/content/caffeine/

Si echamos un vistazo a las demás entradas en installed-chrome veremos que algunas comienzan con skin, otras con locale y otras con contents. Esto es lo único que tenemos que cambiar a la hora de registrar skins y locales, lo demás es similar, por lo tanto para nuestra aplicación de ejemplo tendríamos que añadir las líneas:

skin,install,url,resource:/chrome/caffeine/content/caffeine/
locale,install,url,resource:/chrome/caffeine/locale/es-ES/
content,install,url,resource:/chrome/caffeine/skin/classic/caffeine/