Es atractiva la posibilidad de “embeber” (“encajar”, “incrustar”) el OPAC como parte del sitio web de la biblioteca, en lugar de presentarlo como una página o sitio que debe ser visitado en forma separada. La idea puede encontrarse, por ejemplo, en esta presentación de Daniel Forsman (2007), de la Biblioteca de Jönköping University (Suecia).
La manera de implementar esto dependerá de las características de la herramienta usada para administrar el sitio; en el caso particular del INMABB nos interesaba poder hacerlo con DokuWiki. Con ese fin, hubo que realizar varias modificaciones en OpacMarc, y crear un plugin para DokuWiki. A continuación se describen los pasos efectuados y los problemas encontrados.
Es importante resaltar que los cambios hechos en OpacMarc posiblemente sean suficientes para permitir que también sea embebido en otras aplicaciones.
Para hacer el opac “embeddable”, tuvimos que hacerle algunas modificaciones.
Definimos un nuevo parámetro output en opac.xis
. Un cliente puede especificar –mediante output=embed– que sólo desea recibir el contenido propiamente, es decir, que opac.xis
debe omitir generar el comienzo (hasta el header inclusive) y el final de la página (posiblemente un footer, y el string “</body></html>”)
Definimos un parámetro script_url en opac.xis
. Mediante este parámetro, un cliente puede sobrescribir el valor del parámetro de configuración SCRIPT_URL. El valor es utilizado como “prefijo” en todas las URLs que apuntan al OPAC, tanto links como formularios.
Por ejemplo, para DokuWiki tendríamos script_url=/doku.php/catalogo (si se configura DokuWiki con userewrite=2), o script_url=/doku.php?id=catalogo (con el default userewrite=0).
Para poder hacer uso de este parámetro, tuvimos que efectuar este reemplazo en varios archivos:
getenv('SCRIPT_NAME')
⇒ v6001^u
(o v6001^u[1]
dentro de un grupo repetible)
Para tener en cuenta el caso en que script_url
ya incluye un query string (e.g. script_url=/doku.php?id=catalogo
), hicimos este otro reemplazo en múltiples archivos:
?IsisScript=
⇒ &IsisScript=
Pero esto aún deja sin resolver el caso de los formularios. Para evitar el problema, podríamos limitarnos a admitir como script_url
solamente valores sin query string, para evitar la complicación de los parámetros adicionales en los formularios; de ahí la conveniencia de utilizar en DokuWiki un valor de userewrite diferente de 0.
Sería mejor si pudiéramos quitar estos dos parámetros de todas las URLs:
&IsisScript=xis/opac.xis&db=demo
pues pueden ser insertados por el plugin, como sucede con la portada del OPAC. Pero no es una necesidad.
Creamos un nuevo parámetro para OpacMarc, path_htdocs, con el que un cliente puede sobrescribir el parámetro de configuración PATH_HTDOCS.
El primer problema a resolver es: cómo hacer que las reglas de estilo del opac se mantengan acotadas y no “contaminen” el resto de la página que aloja al opac. La solución es simple:
Por ahora, sólo hice esas modificaciones en una copia de los archivos .css para ser usada por DokuWiki; creo que el cambio finalmente habría que hacerlo en las .css originales de OpacMarc.
Ver qué partes del css del opac son para header/footer (i.e. fuera de ese div) y por lo tanto no deberían llevar ese prefijo en los selectores.
El segundo problema es: cómo evitar que las reglas de estilo de la página host (DokuWiki) causen “interferencias” sobre la porción de la página correspondiente al opac. Aquí a su vez se presentan dos posibles situaciones:
El tercer problema: cómo ajustar los paths de las imágenes usadas por las hojas de estilo, p.ej.
background-image: url(../img/0180_bullet.gif);
Cuarto problema: ¿cómo obtiene el cliente las hojas de estilo e imágenes asociadas? Hay hojas de estilo default, locales, por base, para IE, …
Así como agregamos elementos link y script al <head> de la página del catálogo, también nos gustaría poder alterar el <title>, para que muestre un título generado por el OPAC. ¿Cómo hacemos?
DokuWiki usa XHTML 1.0 Transitional. Para que la inclusión de contenido del OPAC no altere la validez del código XHTML, vamos a tener que hacer algunos ajustes, de manera que OpacMarc produzca XHTML válido.
<br>
⇒ <br/>
<hr>
⇒ <hr/>
<img …>
⇒ <img …/>
<input …>
⇒ <input …/>
selected
⇒ selected=“selected”
checked
⇒ checked=“checked”
&
⇒ &
Hice varios ajustes, pero habrá que revisar más exhaustivamente (sé que dejé algunas cosas colgadas).
Arreglos pendientes, según validador de W3C:
Implementamos la funcionalidad “encajar OpacMarc en una página del wiki” mediante un plugin llamado opacmarc.
El plugin define esta sintaxis:
{{OPAC>nombre_de_la_base}}
(Para usar algo como {{OPAC>demo}}
(análogo a la sintaxis de blog o rss), tenemos que elegir adecuadamente el valor retornado por la función getSort, para poder “ganarle” a la sintaxis usada para insertar media. Ver devel:syntax_plugins#sort_number y devel:parser:getsort_list.)
Los archivos creados son:
syntax.php
action.php
conf/metadata.php
conf/default.php
lang/en/settings.php
lang/es/settings.php
El archivo action.php
(action plugin) se ocupa de insertar elementos script
y link
en el head de la página, para solicitar CSS y JavaScript directamente al servidor del OPAC. Esto lo hace solamente para la página del catálogo. Así, el plugin no necesita mantener una copia del CSS ni del JS del OPAC. Un inconveniente a resolver: ¿cómo hacer que esta modificación sólo suceda en la página del catálogo? No queremos tener que reconocer la página mediante su id; se supone que es la presencia de la sintaxis {{OPAC...}}
lo que caracteriza a la página como “catálogo”. Ver si se puede registrar el event handler desde syntax.php (devel:events#registering_to_receive_an_event). Probé y no dio resultado. Consultar en la lista.
El primer síntoma fue que por cada “búsqueda por autor”, que normalmente genera un único archivo temporal, al usar DokuWiki se generaban siete archivos iguales.
Usando estas líneas en opac.xis
:
<file action="append" type="output">/tmp/opacmarc-dokuwiki.log</file> <display><pft>'ejecutando opac.xis'/</pft></display> <file action="close" type="output">/tmp/opacmarc-dokuwiki.log</file>
quedó claro que el problema está en que opac.xis
se está ejecutando siete veces, incluso al visitar la página de inicio del catálogo.
Usando estas líneas en syntax.php
:
$fp = fopen('/tmp/opacmarc-dokuwiki-syntax', 'a'); fwrite($fp, "syntax-render\n"); fclose($fp);
nos enteramos de que es la función render en syntax.php
la que se está ejecutando siete veces. (El resto del código en ese archivo aparentemente sólo se ejecuta una vez.)
Haciendo un test similar con el plugin now, encontramos que:
En pruebas posteriores, el número siete baja a dos, pero en cualquier caso la pregunta es: ¿por qué render() se ejecuta más de una vez?
Consulta enviada al foro.
Instalé Xdebug para PHP (sudo apt-get install php5-xdebug
) para tratar de ver mejor lo que está pasando. Ver Understanding PHP code better with Xdebug
Usando Xdebug veo que en renderer.php
, class Doku_Renderer
, la función plugin
es llamada 7 veces; quien llama es call_user_func_array
en parserutils.php
.
Consulta enviada a la lista de desarrolladores.
Probar con una instalación completamente limpia del wiki (template default, etc.).
Para ver si influye la presencia de links hacia la misma página: Creé una página “instituto/test”, con el contenido “[OPAC>demo]”. Al ver la página no aparecen links a ella misma. La función render se sigue ejecutando 7 veces. ver efecto de los breadcrumbs. OJO! Ver la config:useheading. También ver valor de $mode en cada ejecución de render.
Al desactivar config:useheading se producen tres llamadas a render: una con $mode=xhtml y dos con $mode=metadata. Antes eran una con $mode=xhtml y seis con $mode=metadata.
Si bien la función render se sigue ejecutando muchas veces (lo que parecería ser un comportamiento normal del wiki), resolví lo de las múltiples llamadas al OPAC mediante un sencillo cache: almaceno la respuesta del OPAC en una variable la primera vez que se ejecuta render, y en las siguientes veces no vuelve a ejecutar ese bloque de código.
Mejor solución: moví el bloque de código al interior del if:
if($mode == 'xhtml') { ... }
ya que es allí donde lo necesitamos; las llamadas extra a render tienen $mode='metadata'.
Explicar por qué no podemos realizar la llamada al OPAC dentro de la función handle (cuyo resultado sí es guardado en cache), y en cambio debemos hacerla desde render (que no se cachea).
Ver discusión en la lista: plugin render() called multiple times for metadata (mayo 2009).
Warning: preg_replace_callback() [function.preg-replace-callback]: Compilation failed: invalid UTF-8 string at offset 20 in /home/fernando/www/html/dokuwiki/inc/html.php on line 271
Cómo se produce: entrar por índice de autores a Raúl Alfonsín, ver el registro, clic en el punto de acceso para Raúl Alfonsín. Se repite si desde ahí hago clic en “Catálogo”, y desaparece cuando insisto.
Esto está relacionado con el resaltado de términos, al hacer una búsqueda con términos acentuados. Ver abajo.
El wiki aplica un resaltado en algunas páginas, mediante un <span class=“search_hit”>. Esto se debe a una interferencia del parámetro query usado para el OPAC. Detalles:
En doku.php se define $HIGH:
$HIGH = $_REQUEST['s']; if(empty($HIGH)) $HIGH = getGoogleQuery();
que a su vez puede depender de getGoogleQuery, definida en inc/common.php:
/** * extracts the query from a search engine referrer * * @author Andreas Gohr <andi@splitbrain.org> * @author Todd Augsburger <todd@rollerorgans.com> */ function getGoogleQuery(){ $url = parse_url($_SERVER['HTTP_REFERER']); if(!$url) return ''; $query = array(); parse_str($url['query'],$query); if(isset($query['q'])) $q = $query['q']; // google, live/msn, aol, ask, altavista, alltheweb, gigablast elseif(isset($query['p'])) $q = $query['p']; // yahoo elseif(isset($query['query'])) $q = $query['query']; // lycos, netscape, clusty, hotbot elseif(preg_match("#a9\.com#i",$url['host'])) // a9 $q = urldecode(ltrim($url['path'],'/')); if(!$q) return ''; $q = preg_split('/[\s\'"\\\\`()\]\[?:!\.{};,#+*<>\\/]+/',$q,-1,PREG_SPLIT_NO_EMPTY); return $q; }
En inc/html.php se utiliza $HIGH para aplicar el resaltado:
/** * show a wiki page * * @author Andreas Gohr <andi@splitbrain.org> */ function html_show($txt=''){ global $ID; global $REV; global $HIGH; global $INFO; ... ... if ($REV) print p_locale_xhtml('showrev'); $html = p_wiki_xhtml($ID,$REV,true); $html = html_secedit($html,$secedit); if($INFO['prependTOC']) $html = tpl_toc(true).$html; $html = html_hilight($html,$HIGH); echo $html; ... }
/** * Highlights searchqueries in HTML code * * @author Andreas Gohr <andi@splitbrain.org> * @author Harry Fuecks <hfuecks@gmail.com> */ function html_hilight($html,$phrases){ $regex = join('|',array_map('preg_quote_cb',array_filter((array) $phrases))); if ($regex ==== '') return $html; $html = preg_replace_callback("/((<[^>]*)|$regex)/ui",'html_hilight_callback',$html); return $html; } /** * Callback used by html_hilight() * * @author Harry Fuecks <hfuecks@gmail.com> */ function html_hilight_callback($m) { $hlight = unslash($m[0]); if ( !isset($m[2])) { $hlight = '<span class="search_hit">'.$hlight.'</span>'; } return $hlight; }
El resaltado está atrasado; es decir, se resaltan términos correspondientes a la búsqueda previa.
Cuestiones a resolver:
.search_hit {background-color: inherit; color: inherit;}
), pero esto no resuelve el problema de las expresiones con acentos, donde se produce un error de PHP. Entonces, como solución de emergencia, comenté en inc/common.php las dos líneas de getGoogleQuery donde se hace referencia a un parámetro “query”. Claro que esto no es bueno, porque estamos alterando código core de DokuWiki. No funcionan las búsquedas cuando se ingresan términos con acentos.
Resuelto aplicando utf8_decode a ciertos parámetros, en base a la presencia de $_REQUEST['form']. Es importante tener en cuenta que el decode es necesario para términos procedentes de un form (i.e. ingresados por un usuario), pero no para aquellos procedentes de un link (i.e. generados por el OPAC). Esto llevó a crear un parámetro oculto form
en los formularios del OPAC.
Queda algún problema pendiente. Buscar registros de “Unión Matemática Argentina”, y desde uno de ellos clic en “Listado”, da error.
¿Cómo podemos usar comentarios condicionales para cargar las hojas de estilo que sólo debe ver IE?
Mediante action.php: no parece que se puedan añadir comentarios.
Mediante el template (archivo meta.html
): no parece buena idea introducir elementos propios del plugin dentro de un template, pero podría ser aceptable para nuestro caso.
Si entramos a un registro directamente desde el índice de autores y pasamos a la ficha, no la muestra; si en cambio pasamos antes por otro estilo y luego intentamos otra vez la ficha, sí se ve. La diferencia que pude detectar en las URLs:
&curr=1&total=1&cn=&style=Ficha
versus
&curr=1&total=&cn=&style=Ficha
Ahora aparece RESUELTO (no sé por qué).
Los logs que almacene OpacMarc carecerán de datos sobre el cliente (número de IP, browser), a menos que el plugin se ocupe de incluirlos en la petición.
~~NOCACHE~~