7.4. Creando CGIs y plantillas

Con una API definida e implementada, es el turno de crear los clientes que han de interactuar con ella: los CGIs y plantillas en mason. Tal y como vimos en Sección 7.1, nuestro módulo va a poder prestar el servicio de sincronización a un cliente de la red. En Sección 7.3 implementamos los métodos necesarios para realizar esta habilitar o deshabilitar este servicio. Ahora crearemos dos CGIs y una plantilla en mason que van hacer uso de esos métodos y mostrarán información sobre el estado del servicio al usuario.

El primer CGI es EBox::CGI::NTP::Index, que hereda de la clase EBox::CGI::ClientBase e implementa el constructor de la clase en el que le pasaremos: el título y la plantilla en mason a utilizar. Veamos la implementación:

Ejemplo 7.11. Constructor del CGI EBox::CGI::NTP::Index

package EBox::CGI::NTP::Index;

use strict;
use warnings;

use base 'EBox::CGI::ClientBase';

use EBox::Global;
use EBox::Gettext;

sub new {
	my $class = shift;
	my $self = $class->SUPER::new('title'    => NTP,
			'template' => 'ntp/index.mas', @_);

	$self->{domain} = "ebox-ntp";
	bless($self, $class);
	return $self;
}  

Fijémonos en un detalle interesante, la cadena title de este CGI no es traducible y es por ello que no seguimos las indicaciones de Sección 2.4.1 acerca del uso de cadenas en el desarrollo de módulos. En el caso de que el título de alguno de nuestros CGIs fuera traducible, sí deberiamos seguir las indicaciones de Sección 2.4.

Pasemos ahora a implementar el método _process que va a obtener la información sobre el estado del servicio de sincronización del módulo y se la va a pasar a la plantilla en mason para que la muestre.

Ejemplo 7.12. Envío del estado del servicio a la plantilla mason

sub _process
{
   my $self = shift;
   my $ntp = EBox::Global->modInstance('ntp');

   my @array = ();
   my $active = 'no';

   if ($ntp->service()) {
      $active = 'yes';
   }

   push (@array, 'active'     => $active);
   $self->{params} = \@array;
}

Como podemos ver, lo primero que hacemos es pedir a EBox::Global una instancia de nuestro módulo ntp, sobre el que realizaremos una llamada al método service. Esta llamada nos retorna el estado del servicio y se lo pasamos a plantilla mason mediante el atributo param. En este caso solo vamos a necesitar pasarle un dato a la plantilla, pero si necesitáramos pasarle mas datos bastaría con añadirlos a la variable array.

Acabamos de implementar el CGI con el que pasamos el estado del servicio de sincronización a la plantilla en mason. Pasemos a implementar el CGI que le complementa, que recibe el estado que el usuario ha seleccionado y se lo pasa al módulo.

Ejemplo 7.13. CGI que habilita o deshabilita el servicio NTP

package EBox::CGI::NTP::Enable;

use strict;
use warnings;

use base 'EBox::CGI::ClientBase';

use EBox::Global;
use EBox::Gettext;

sub new 
{
	my $class = shift;
	my $self = $class->SUPER::new('title' => 'NTP', @_);
	$self->{redirect} = "NTP/Index";
	$self->{domain} = "ebox-ntp";
	bless($self, $class);

	return $self;
}

sub _process
{
	my $self = shift;
	my $ntp= EBox::Global->modInstance('ntp');

	$self->_requireParam('active', __('module status'));
	$ntp->setService(($self->param('active') eq 'yes'));
}

1;  

Vemos que la implementación es muy sencilla, tan solo tenemos que tener en cuenta dos detalles.

Por un lado que en el constructor establecemos el atributo redirect con el valor de NTP/Index para que cuando establezcamos el nuevo estado del servicio, se llame de nuevo a ese CGI para actualizar el valor del estado del servicio que se muestra al usuario.

El otro detalle que debemos fijarnos es la llamada a setService en la que recogemos el parámetro active de la petición HTTP mediante la llamada $self->param('active').

Vamos a implementar ahora la plantilla mason que nos permite mostrar al usuario el estado del servicio de sincronización y modificarlo. Este es un caso un tanto especial, casi todos los módulos que se desarrollen para eBox van a necesitar habilitar e deshabilitar el servicio. Para que en todos ellos se haga de una manera similar se implementó en el sistema base la plantilla enable.mas.

La manera de utilizarla es sencilla, nos creamos una plantilla que recibe como parámetro el estado del servicio. Tal y como se explicó en Sección 5.2 podemos incluir una plantilla mason dentro de otra plantilla mediante:

		<& plantilla.mas, @parametros &> 

. Nosotros incluiremos la plantilla enable.mas en la que nos estamos implementando y le pasaremos como parámetros el título y el estado del servicio de sincronización. Veamos como quedaría su implementación:

Ejemplo 7.14. Plantilla mason para habilitar el servicio NTP

<%args> $active </%args>
<%init> use EBox::Gettext; </%init>

<div class='ntpnew'>
<br />
<& enable.mas, title => __('Enable the local NTP server'),
		active => $active &>
</div>

Sin embargo este sistema nos obliga a que el CGI que se encargue de habilitar o deshabilitar el servicio se ha de llamar Enable ya que quien realiza la llamada a este CGI no es nuestra plantilla mason, si no la plantilla mason predefinida enable.mas. Si echamos otro vistazo al CGI que realiza esta operación, vemos que hemos llamado a la clase como EBox::CGI::NTP::Enable con lo que cumplimos este requerimiento.

En este momento nos queda por ver como están implementados los CGIs para cambiar la fecha y hora del sistema de manera manual, cambio de la zona horaria y el establecimiento del servicio de sincronización mediante servidores externos junto con sus plantillas en mason. La implementación de estos CGIs y plantillas es bastante sencilla, para ver el código puede ir al repositorio de subversion y descargarlo libremente. El lector podrá realizar una lectura del código sin problemas asi que no entraremos a explicar el código en profundidad y simplemente explicaremos cómo están relacionados y que es lo que hace cada uno de los ficheros.

Tenemos dos partes bien diferenciadas, por un lado vamos a poder cambiar la zona horaria del sistema cuya gestión la realizaremos mediante dos CGIs.

Tan solo quedaría comentar un pequeño detalle del CGI TimeZoner. En él mandamos a la plantilla en mason los valores de continente y país que tiene el sistema en ese momento y por otro lado le mandamos un array con todos los continentes posibles y una tabla hash en la que se relacionan cada uno de los continentes anteriores con un array con los paises que pertenecen a ese continente. Toda esta información nos está accesible en el fichero /usr/share/zoneinfo/zone.tab.

La otra parte es el cambio de fecha y hora del sistema, que bien lo podremos realizar manualmente o sincronizándonos a través de servidores ntp externos. La implementación de estas opciones va a ser excluyente. Vamos a tener el CGI Datetime, cuya misión va a ser enviar toda información acerca de la fecha y hora actual del sistema, el estado del servicio de sincronización externa y los servidores ntp externos almacenados en la configuración interna de gconf. Para establecer los nuevos valores que el usuario haya elegido vamos a tener dos CGIs: Synch cuyo trabajo será habilitar el servicio de sincronización externa y ChangeDate que como podemos adivinar establecera la nueva fecha y hora del sistema.

Hemos dicho antes que la opción de establecer la fecha y hora de manera manual o mediante sincronización externa son excluyentes, tarea realizada mediante las plantillas en mason. Veamos como implementarlo. Por un lado tenemos la plantilla datetime.mas que recibe toda información del CGI Datetime, carga la plantilla mason synch.mas que ofrece la posibilidad de arrancar o no el servicio de sincronización externa y, dependiendo de si está activado o no, mostrará la plantilla de selección de servidores ntp externos a los que sincronizarse(servers.mas) o permitirá cambiar manualmente la fecha y hora del sistema mediante otra plantilla (date.mas) si el servicio de sincronización externa está habilitado.

Ejemplo 7.15. Código de plantilla mason de selección de plantillas

<& /ntp/synch.mas, title => __('Synchronize with external NTP servers'),
synchronized => $synchronized &>

% if ($synchronized eq 'yes') {
<& /ntp/servers.mas, title => __('External NTP servers'), servers => \@servers
&>
% }

% if ($synchronized eq 'no') {
<& /ntp/date.mas, title => __('Change Date and Time'), date => \@date &>
% }

Las plantillas synch.mas, server.mas y date.mas simplemente muestran la información que desde la plantilla datetime.mas se les manda.