Tutorial de Apache: Introducción a las directivas interpretadas por el servidor (Server Side Includes)


Tutorial de Apache: Introducción a las directivas interpretadas por el servidor (Server Side Includes)

Relación de Módulos

mod_include
mod_cgi
mod_expires
Relación de Directivas

Options
XBitHack
AddType
AddHandler
BrowserMatchNoCase

Este CÓMO (HOWTO) apareció primero en Apache Today (http://www.apachetoday.com/) como una serie de tres artículos. Se reproducen aquí por acuerdo con ApacheToday e Internet.com.

Este artículo trata de las instrucciones Server Side Includes, denominadas normalmente SSI. En este artículo se explica la configuración del servidor para permitir SSI e introduce algunas técnicas básicas para añadir contenido dinámico en las páginas HTML, utilizando SSI.

En la última parte del artículo, trataremos sobre algunos aspectos más avanzados que se pueden hacer con SSI como, por ejemplo, declaraciones condicionales en las directivas SSI.


¿Qué son las SSI?

SSI (Server Side Includes) son directivas que se pueden incluir en las páginas HTML y que son evaluadas por el servidor mientras las páginas son servidas. Permiten generar contenido dinámicamente en una página HTML sin tener que enviar la página completa al servidor mediante una interfaz común de acceso (CGI) o con alguna otra tecnología dinámica.

La decisión de cuándo usar SSI o cuándo tener las páginas generadas completamente por medio de otro programa depende, normalmente, de la cantidad de elementos estáticos que forman la página y de cuánto se necesita recalcular cada vez que la página es procesada. SSI es una buena fórmula de añadir pequeñas piezas de información. Pero si la mayor parte de la página es generada al mismo tiempo que se procesa, se recomienda buscar alguna otra solución.


Configurar el servidor para permitir las instrucciones SSI

Para permitir las instrucciones SSI en tu servidor debes tener la siguiente directiva, bien en el fichero httpd.conf o bien en .htaccess:

        Options +Includes

Con esto el servidor Apache procesa ficheros con las directivas SSI.

No se procesa cualquier fichero. Se debe codificar en Apache qué ficheros serán procesados. Hay dos maneras de proceder. Se puede configurar el servidor Apache para procesar los ficheros que tengan una extensión particular como, por ejemplo, .shtml, con las directivas:

        AddType text/html .shtml
        AddHandler server-parsed .shtml

La desventaja de esta aproximación es que si se quieren añadir directivas SSI a páginas ya creadas, se deberán cambiar los nombre de estas páginas y, consecuentemente, todos los enlaces a las mismas, dándoles la extensión .shtml, para que las directivas puedan ser procesadas.

El otro método es usar la directiva XBitHack:

        XBitHack on

La directiva XBitHack provoca que el servidor Apache procese ficheros con las directivas SSI si son ejecutable. Así pues, para añadir las directivas SSI en páginas ya creadas, en vez de tener que cambiar el nombre del fichero, solamente se necesita hacer el fichero ejecutable usando el comando chmod.

        chmod +x pagename.html

Un pequeño comentario sobre lo que no se debería hacer. Algunas personas recomiendan configurar Apache para que procese todos los ficheros .html mediante SSI, así no habrá confunsión con los ficheros con extensión .shtml. Estas personas quizás no han oído nada sobre la directiva XBitHack. Se debe tener en cuenta que con esta manera de proceder se está requiriendo que el servidor apache lea a lo largo de cada línea de los ficheros que se envían al cliente, incluso si no contienen ninguna directiva SSI. Esto puede provocar lentitud en los procesos y no es la mejor manera de actuar.

Por supuesto, en Windows, no existe la posibilidad de hacer ejecutable un fichero lo que limita un poco las posibilidades de configuración.

En su configuración por defecto, Apache no envía la última fecha de modificación o el tamaño del contenido de la cabecera HTTP en las páginas SSI, porque estos valores son difíciles de calcular para contenidos dinámicos. Esto puede impedir que el documento se almacene en la memoria caché, provocando una mayor lentitud en su presentación por el cliente. Hay dos formas de solucionar esto:

  1. Usar la configuración XBitHack Full. Esto provoca que Apache determine la última fecha de modificación mirando únicamente la fecha del fichero original devuelto, ignorando la fecha de modificación de cualquier otro fichero incluido.
  2. Usar la directiva proporcionada por mod_expires para poner una fecha explícita de expiración en el fichero, permitiendo, de este modo, a los navegadores y las máqinas proxy saber que es aceptable para su memoria caché.

Directivas básicas SSI

Las directivas SSI tienen la siguiente sintaxis:

        <!--#elemento atributo=valor atributo=valor ... -->

Su formato es el mismo que el de un comentario en HTML, de esta forma si no están bien formadas, el navegador las ignorará, pero permanecerán visibles en el formato fuente de HTML. Si la directiva SSI está correctamente configurada será reemplazada por su resultado correspondiente.

El elemento puede ser uno de un número determinado, veremos algo más sobre esto en el próximo apartado de esta serie. Por ahora, aquí están algunos ejemplos de lo que se puede hacer con SSI.

Fecha actual

        <!--#echo var="DATE_LOCAL" -->
El elemento echo presenta el valor de una variable. Hay un número determinado de variables estándar, que incluyen todo el conjunto de variables de entorno que son accesibles mediante programas CGI. También se pueden definir variables específicas mediante el elemento set.

Si el formato en el que se presenta la fecha no es el preferido se puede usar el elemento config, con el atributo timefmt, para modificar este formato.

        <!--#config timefmt="%A %B %d, %Y" -->
        Fecha actual <!--#echo var="DATE_LOCAL" -->

Modificación de la fecha de fichero

        Última fecha de modificación del fichero <!--#flastmod file="index.html" -->
Este elemento está también sujeto a configuración con el formato timefmt.

Incluyendo los resultados de una interfaz común de acceso (CGI)

Presentar los resultados de una interfaz común de acceso (CGI) es uno de los usos más comunes de SSI, como, por ejemplo, el favorito de la mayoría, presentar el resultado de un contador de visitas.

        <!--#include virtual="/cgi-bin/counter.pl" -->


Ejemplos adicionales

A continuación se presentan algunos ejemplos específicos de otros usos que se pueden presentar en documentos HTML con SSI.


¿Cuándo fue modificado este documento?

Earlier, we mentioned that you could use SSI to inform the user when the document was most recently modified. However, the actual method for doing that was left somewhat in question. The following code, placed in your HTML document, will put such a time stamp on your page. Of course, you will have to have SSI correctly enabled, as discussed above.

        <!--#config timefmt="%A %B %d, %Y" -->
        This file last modified <!--#flastmod file="ssi.shtml" -->

Of course, you will need to replace the ssi.shtml with the actual name of the file that you're referring to. This can be inconvenient if you're just looking for a generic piece of code that you can paste into any file, so you probably want to use the LAST_MODIFIED variable instead:

        <!--#config timefmt="%D" -->
        This file last modified <!--#echo var="LAST_MODIFIED" -->

Para saber más detalles sobre el formato timefmt, puede acceder a su buscador favorito y buscar ctime. La sintaxis es la misma.


Incluir un final de fichero estándar

If you are managing any site that is more than a few pages, you may find that making changes to all those pages can be a real pain, particularly if you are trying to maintain some kind of standard look across all those pages.

Using an include file for a header and/or a footer can reduce the burden of these updates. You just have to make one footer file, and then include it into each page with the include SSI command. The include element can determine what file to include with either the file attribute, or the virtual attribute. The file attribute is a file path, relative to the current directory. That means that it cannot be an absolute file path (starting with /), nor can it contain ../ as part of that path. The virtual attribute is probably more useful, and should specify a URL relative to the document being served. It can start with a /, but must be on the same server as the file being served.

        <!--#include virtual="/footer.html" -->

Frecuentemente combinaremos las dos cosas, colocando la directiva LAST_MODIFIED inside a footer file to be included. SSI directives can be contained in the included file, and includes can be nested - that is, the included file can include another file, and so on.


¿Qué más se puede configurar?

In addition to being able to config the time format, you can also config two other things.

Usually, when something goes wrong with your SSI directive, you get the message

        [se ha producido un error mientras se procesaba esta directiva]

If you want to change that message to something else, you can do so with the errmsg attribute to the config element:

        <!--#config errmsg="[It appears that you don't know how to use SSI]" -->

Hopefully, end users will never see this message, because you will have resolved all the problems with your SSI directives before your site goes live. (Right?)

And you can config the format in which file sizes are returned with the sizefmt attribute. You can specify bytes for a full count in bytes, or abbrev for an abbreviated number in Kb or Mb, as appropriate.


Ejecutando comandos

I expect that I'll have an article some time in the coming months about using SSI with small CGI programs. For now, here's something else that you can do with the exec element. You can actually have SSI execute a command using the shell (/bin/sh, to be precise - or the DOS shell, if you're on Win32). The following, for example, will give you a directory listing.

        <pre>
        <!--#exec cmd="ls" -->
        </pre>

o, en Windows

        <pre>
        <!--#exec cmd="dir" -->
        </pre>

You might notice some strange formatting with this directive on Windows, because the output from dir contains the string ``<dir>'' in it, which confuses browsers.

Note that this feature is exceedingly dangerous, as it will execute whatever code happens to be embedded in the exec tag. If you have any situation where users can edit content on your web pages, such as with a ``guestbook'', for example, make sure that you have this feature disabled. You can allow SSI, but not the exec feature, with the IncludesNOEXEC argument to the Options directive.


Técnicas avanzadas SSi

In addition to spitting out content, Apache SSI gives you the option of setting variables, and using those variables in comparisons and conditionals.

Caveat

La mayor parte de los aspectos presentados en este artículo solamente son válidos para la versión 1.2 o posteriores de Apache. Naturalmente, se recomienda actualizar cuanto antes mejor. Adelante, este es un buen momento. Esperaremos.


Fijando variables

Usando la directiva set, se pueden fijar variable para usarlas posteriormente. We'll need this later in the discussion, so we'll talk about it here. La sintaxis para esto es la siguiente:

        <!--#set var="name" value="Rich" -->

In addition to merely setting values literally like that, you can use any other variable, including, for example, environment variables, or some of the variables we discussed in the last article (like LAST_MODIFIED, for example) to give values to your variables. You will specify that something is a variable, rather than a literal string, by using the dollar sign ($) before the name of the variable.

        <!--#set var="modified" value="$LAST_MODIFIED" -->

Para colocar el signo del dolar como valor dentro de una variable, es necesario escaparlo con el backslash.

        <!--#set var="cost" value="\$100" -->

Por último, if you want to put a variable in the midst of a longer string, and there's a chance that the name of the variable will run up against some other characters, and thus be confused with those characters, you can place the name of the variable in braces, to remove this confusion. (It's hard to come up with a really good example of this, but hopefully you'll get the point.)

        <!--#set var="date" value="${DATE_LOCAL}_${DATE_GMT}" -->

Expresiones condicionales

Now that we have variables, and are able to set and compare their values, we can use them to express conditionals. This lets SSI be a tiny programming language of sorts. mod_include provides an if, elif, else, endif structure for building conditional statements. This allows you to effectively generate multiple logical pages out of one actual page.

La estructura de las construcciones condicionales es:

        <!--#if expr="test_condition" -->
    <!--#elif expr="test_condition" -->
    <!--#else -->
    <!--#endif -->

Una test_condition (condición de prueba) puede ser alguna clase de comparación lógica - comparando un valor dado con otro o probando el "valor de verdad" de un valor particular. (Una cadena dada es verdadera si no está vacía). Para poder consultar una lista completa de los operadores de comparación disponibles, se puede consultar la documentación de mod_include. A continuación se presentan algunos ejemplos de cómo se pueden usar estas construcciones.

En el fichero de configuración se puede poner la siguiente línea:

        BrowserMatchNoCase macintosh Mac
        BrowserMatchNoCase MSIE InternetExplorer

This will set environment variables ``Mac'' and ``InternetExplorer'' to true, if the client is running Internet Explorer on a Macintosh.

Then, in your SSI-enabled document, you might do the following:

        <!--#if expr="${Mac} && ${InternetExplorer}" -->
        Apologetic text goes here
        <!--#else -->
        Cool JavaScript code goes here
        <!--#endif -->

Not that I have anything against IE on Macs - I just struggled for a few hours last week trying to get some JavaScript working on IE on a Mac, when it was working everywhere else. The above was the interim workaround.

Any other variable (either ones that you define, or normal environment variables) can be used in conditional statements. With Apache's ability to set environment variables with the SetEnvIf directives, and other related directives, this functionality can let you do some pretty involved dynamic stuff without ever resorting to CGI.


Conclusión

Ciertamente, SSI no pretende reemplazar a los programas CGI o a otras tecnologías usadas para generar páginas dinámicamente, pero es una manera cómoda y sencilla de añadir pequeñas cantidades de contenido dinámico en las páginas HTML, sin realizar mucho trabajo extra.