Your SlideShare is downloading. ×
Desarrollo de aplicaciones web usando Catalyst y jQuery
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Saving this for later?

Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime - even offline.

Text the download link to your phone

Standard text messaging rates apply

Desarrollo de aplicaciones web usando Catalyst y jQuery

2,584
views

Published on

Ponencia presentada en las terceras jornadas de software libre realizadas en el iuta de maracay el sábado 3 de noviembre 2007

Ponencia presentada en las terceras jornadas de software libre realizadas en el iuta de maracay el sábado 3 de noviembre 2007

Published in: Technology

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
2,584
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
42
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Javier E. Pérez P. Noviembre 2007 Desarrollo de aplicaciones web usando Catalyst y jQuery
  • 2. Puntos a tratar
    • ¿Qué es Catalyst?
    • Ventajas de su uso.
    • Requisitos de instalación.
    • Creando un proyecto.
    • Estructura de proyecto.
    • Creación de: Controlador, Modelo, Vista.
    • Agregando módulos.
    • Conexión a base de datos (DBIC).
    • Trabajando con plantillas (TT, TTSite)
    • Trabajando con formularios (FormBuilder).
    • Uso de sessiones.
    • Autorización, autenticación.
    • Depuración.
    • Consejos.
    • Proyectos nacionales desarrollados usando catalyst.
  • 3. ¿Qué es Catalyst?
    • Framework Web escrito usando perl.
    • MVC.
    • Unicode.
    • Servidor de pruebas integrado.
  • 4. Metodología MVC
      • Modelo
        • De donde se almacenan los datos.
        • Generalmente base de datos.
      • Vista
        • La presentación de los datos.
        • HTML, JSON, RSS, XML, etc.
      • Controlador
        • Quién maneja las transacciones entre la solicitud del usuario, el proceso y salida de información.
        • Catalyst itself
  • 5. Ventajas de su uso
  • 6. Ventajas de su uso
    • Despacho del URL, se trabaja por segmentos en vez de querystring's
    • Instalación sencilla.
    • Estructura establecida de los directorios manteniendo un orden.
    • Está respaldado por la gran cantidad de módulos que hospeda cpan.
      • Formularios
      • ORM's
      • Reportes
      • i18n
      • autenticatión, autorización.
      • etc.
  • 7. Ventajas de su uso
    • Despacho del URL, se trabaja basado en segmentos en vez de querystring's.
    http://www.google.com/search ?hl=es&client=iceweasel-a&q=catalyst&btnG=Buscar http://www.administracion.com/usuario ?id=11222333&accion=eliminar QueryString http://www.google.com/search/ lenguale/es/cliente/iceweasel-a/q/catalyst/Buscar http://www.administracion.com/usuario /11222333/eliminar Basado en segmentos (segment based)
  • 8.
    • Está respaldado por la gran cantidad de módulos que hospeda cpan.
    “ there's nothing magical about catalyst, it doesn't get in your way, it just dispatches urls to actions” Ventajas de su uso use PDF::CreateSimple; sub pdf : Local { my ($self,$c,$mensaje) = @_; # Heredamos el módulo como lo haríamos con cualquier aplicación CGI my $pdfFile = PDF::CreateSimple->new("root/reporte.pdf",undef,'LETTER'); # Pasamos algunos parametros (Esto no es catalyst, es perl) $pdfFile->drawText($mensaje,'Verdana',10,200,450,'black',3); $pdfFile->drawText('Generado con Catalyst','Verdana',10,200,400,'black',3); $pdfFile->drawImage('root/images/catalyst-logo.png',250,300); # esto no envía el pdf para descargar, sino que lo guarda en el disco $pdfFile->closeFile; # Ahora enviamos al navegador a que muestre el archivo recién guardado $c->res->redirect("/archivo.pdf"); }
  • 9.
      • Por supuesto, TIMTOWTDI
      • (There Is More Than One Way To Do It)
  • 10. Instalación
    • Paquetes en debian / ubuntu :
      • libcatalyst-perl
      • libcatalyst-modules-perl
    • Módulos usando cpan:
      • Catalyst
      • El resto que se necesite.
        • Por ejemplo, en la shell: cpan CGI::FormBuilder
        • ó usar dh_make para convertir modulos de perl a paquetes debian y así instalarlos.
        • $ catalyst.pl proyecto
        • $ cd proyecto/
        • $ perl script/proyecto_server.pl
  • 11. Creando un proyecto
    • Creamos proyecto
      • $ catalyst.pl proyecto
    • Nos cambiamos de directorio de trabajo al recien creado (nombre del proyecto)
      • $ cd proyecto
    • Corremos el servidor de pruebas
      • $ perl script/proyecto_server.pl
  • 12.
    • Estructura establecida de los directorios manteniendo un orden.
  • 13. Creando controlador
    • perl script/sistap_create.pl controller unesco_area
    • lib/sistap/Controller/unesco_area.pm
    http://localhost:3000/ unesco_area / saludo
    • Controlador
    • Acción
    package sistap::Controller::unesco_area; use strict; use warnings; use base 'Catalyst::Controller'; sub index : Private { my ( $self, $c ) = @_; $c->response->body( 'Hola mundo' ); } sub saludo : Local { my ( $self, $c ) = @_; $c->response->body( 'Hola mundo... de nuevo' ); } 1;
  • 14. Métodos de despacho
    • Local (: Local {})
      • Reconoce el nombre de la acción como primer argumento del controlador.
    • Path (: Path('foo/bar') { })
      • Se especifica una ruta absoluta a despachar.
    • Global (: Global { })
      • Despacha el primer nivel (como si fuera controlador)
    • Private (: Private {} )
      • Especial para funciones reservadas en catalyst (default, index, begin, end, auto) , no es despachada por url.
    • Regex ( : Regex('^item(d+)/orden(d+)$') { } )
      • Despacha según una expresión regular dada (en todo el sistema)
      • No usa ModRewrite para esto.
      • item4/orden243 es capturada con esa expresión.
    • LocalRegex ( : LocalRegex('^widget(d+)$') { } )
      • Igual que “Regex” pero solo es interpretada en el controlador donde está definida.
      • widget23 es reconocido con la expresión del ejemplo.
    • Chained
      • Se realiza una cadea entre diferentes acciones
    • CaptureArgs() y Args()
      • Se combina con Chained para reconocer la cadena
    sub saludo : Local { my ( $self, $c ) = @_; $c->res->body('dvst'); }
  • 15. Metodos de despacho
    • Chained / CaptureArgs() / Args()
    sub wiki : PathPart('wiki') Chained('/') CaptureArgs(1) { my ( $self, $c, $page_name ) = @_; # carga la página de nombre $page_name y coloca el objeto en el stash $c->stash->{var1} = $page_name; } sub rev : PathPart('rev') Chained('wiki') CaptureArgs(1) { my ( $self, $c, $revision_id ) = @_; # Usa el objeto de página que está en el stash y obtiene el número # de revisión $revision_id. $c->stash->{var2} = $revision_id ; } sub view : PathPart Chained('rev') Args(0) { my ( $self, $c ) = @_; # Muestra la revisión de la página en pantalla, my $salida ; $salida = "Esta pantalla muestra la revision: " . $c->stash->{var2} ; $salida .= " de la pagina: " . $c->stash->{var1} ; $c->res->body($salida); } URL: http://localhost:3000/wiki/principal/rev/4/view Salida por pantalla: Esta pantalla muestra la revision: 4 de la pagina: principal sub view : PathPart Chained('wiki') Args(0) { my ( $self, $c ) = @_; # Muestra la revisión de la página en pantalla, my $salida ; $salida = "Esta pantalla muestra la revision: " . $c->stash->{var2} ; $salida .= " de la pagina: " . $c->stash->{var1} ; $c->res->body($salida); }
  • 16. Creando un modelo (DBIx::Class -> Catalyst::Model::DBIC::Schema)
    • Necesitamos esquema. (archivo lib/sistapDB.pm)
    package sistapDB ; =head1 NAME sistapDB - DBIC Schema Class =cut # Nuetro esquema necesita heredar desde 'DBIx::Class::Schema' use base qw/DBIx::Class::Schema/ ; # Se necesitan cargas las clases de modelo de base de datos acá __PACKAGE__->load_classes({ sistapDB => [qw/ unesco_area unesco_subarea unesco_categoria /] }); 1 ;
  • 17. Creando un modelo
    • Se crea una clase por tabla
      • (archivo lib/sistapDB/unesco_area.pm)
    • ó usamos DBIx::Class::Schema::Loader
    package sistapDB::unesco_area; use base qw/DBIx::Class/; # Se cargan componentes requeridos por DBIC __PACKAGE__->load_components( qw/PK::Auto Core/ ); # Se asigna el nombre de la base de datos __PACKAGE__->table( 'sta_unesco_area' ); # Se listan los campos de la tabla __PACKAGE__->add_columns( qw/id codigo nombre descripcion activo / ); # Se indica la llave primaria de la tabla __PACKAGE__->set_primary_key( qw/id/ ); # Asignamos las relaciones __PACKAGE__->has_many( subareas => 'sistapDB::unesco_subarea','id_unesco_area' ); 1 ;
  • 18. Creando un modelo
      • Resultado : (Archivo: lib/sistap/Model/sistapDB)
      • Script helper :
      • .script/sistap_create.pl model sistapDB DBIC::Schema
      • sistapDB dbi:Pg:dbname=sistap 'usuario' 'clave' '{ AutoCommit => 1 } '
      • package DBIC::Model:: sistapDB ;
      • use strict;
      • use base 'Catalyst::Model::DBIC::Schema';
      • __PACKAGE__->config(
      • schema_class => ' sistapDB ',
      • connect_info => [
      • 'dbi:Pg:dbname=sistap',
      • 'usuario',
      • 'clave',
      • { AutoCommit => 1 },
      • ],
      • );
  • 19. Trabajando con relaciones package sistapDB::unesco_area; #... Se hereda clase ; Carga de componentes ; nombre de la tabla ; nombre columnas ; llave primaria __PACKAGE__->add_columns(qw/id_area nombre/); # empezamos a declarar las relaciones a nivel de ORM __PACKAGE__->has_many( subareas => 'sistapDB::unesco_subarea',' id_area '); package sistapDB::unesco_subarea; #... igual que arriba __PACKAGE__->add_columns(qw/id_subarea id_area nombre/); # empezamos a declarar las relaciones a nivel de ORM __PACKAGE__->belongs_to( area => 'sistapDB::unesco_area',' id_area '); __PACKAGE__->has_many( categorias => 'sistapDB::unesco_subarea',' id_subarea '); package sistapDB::unesco_categoria; #... igual que arriba __PACKAGE__->add_columns(qw/id_categoria id_subarea nombre/); # empezamos a declarar las relaciones a nivel de ORM __PACKAGE__->belongs_to( subarea => 'sistapDB::unesco_subarea',' id_subarea ');
  • 20. Usando DBIC en el controlador
      • Métodos más comunes:
      • find ( SELECT .. LIMIT 1 ) : Obtiene un (1) registro (hash) según patrón de busqueda
      • $area = $c->model(“sistapDB::unesco_area”)->find(3);
      • $persona = c->model(“sistapDB::personas”)->find({ nombre => { ILIKE => '%javier%' }})
      • search (SELECT *) : Obtiene un arreglo de registros
      • @productos = $c->model(“sistapDB::productos”)->search({ codigo => 've' , tipo => 'abc' });
      • create (INSERT) : Crea un nuevo registro según el hash pasado.
      • my $campos = { codigo => $c->req->param("codigo"), nombre => $c->req->param(“nombre”)};
      • $registro = $c->model(“sistapDB::productos”)->create($campos);
      • # al asignar la creación del registro a una variable, se obtiene el ResourceSet de la operación
      • $registro->id ; # se obtiene el id del registro recien insertado.
      • update : Actualiza el ResourceSet
      • $equipo = $c->model(“sistapDB::equipos”)->find(3);
      • $equipo->tipo(“ups”);
      • $equipo->dominio(“administracion”);
      • $equipo->update;
      • delete : Elimina los registros del resourceSet
      • $c->model(“sistapDB::equipos”)->search({tipo => 'ups'})->delete;
  • 21. Paginador usando DBIC Plantilla (Template Toolkit) Controlador
      • package sistap::Controller::esta;
      • sub pagina : Local {
      • my ( $self , $c ) = @_ ;
      • my $nroRegistros = $c->req ->param( "nroRegistros" ) || 10;
      • my $nroPagina = $c->req ->param( "nroPagina" ) || 1;
      • my $paginador = $c->model ( "sistapDB::instituciones" )->search(undef,{
      • page => $nroPagina,
      • rows => $nroRegistros
      • }) ;
      • $c->stash->{registros} = $paginador ;
      • }
      • <ul>
      • [% WHILE ( r = registro.next ) %]
      • <li> [% r.nombre %] </li>
      • [% END %]
      • </ul>
      • <form action=”[% c.uri_for('/esta/pagina') %]”>
      • <label for=”nro_pagina”>Nro página</label>
      • <input type=”text” id=”nro_pagina” name=”nroPagina”>
      • <input type=”submit” value=”Ir a pagina”>
      • </form>
  • 22. Vistas
    • TTSite
    • Template Toolkit
    • JSON
    • PHP
    • ClearSilver (yahoo, google)
    • ...
    • Predefiniendo una vista.
  • 23. Vistas (TTSite -> Catalyst::Helper::View::TTSite)
    • ./lib/config/
      • Configuración de variables (colores, rutas predefinidas, etc) a ser usadas.
    • ./lib/site
      • Plantillas fuentes
        • footer : Pie de página
        • heade r: Encabezado (h1 con nombre de página)
        • html : Esqueleto base (Incluye ttsite.css)
        • layout : Cuerpo (body) del documento.
        • wrapper : Quién se encarga de acoplarlos.
    • ./src
      • Plantillas predefinidas.
      • perl script/sistap_create view TTSite TTSite
    . |-- lib | |-- config | | |-- col | | |-- main | | `-- url | `-- site | |-- footer | |-- header | |-- html | |-- layout | `-- wrapper `--- src |-- error.tt2 |-- message.tt2 |-- ttsite.css `-- welcome.tt2
  • 24. Vistas (Template Toolkit)
    • perl script/sistap_create view TT TT
    • Por defecto, las plantillas se almacenan en root
    • $c->stash->{variable} && [% variable %]
  • 25. Vistas (JSON)
    • Catalyst::View::JSON
    • perl script/sistap_create view JSON JSON
    my @estados = $c->model ( &quot;sistapDB::paises&quot; )->find($id_pais)->estados( undef ,{ order_by => ' nombre ' }) ; $c->stash ->{estados} = [ map { { id_estado => $_->id_estado , nombre_estado => $_->nombre } } @estados ]; $c->forward (' sistap::View::JSON '); my @estados = $c->model ( &quot;sistapDB::paises&quot; )->find($id_pais)->estados()->all ; $c->stash ->{estados} = @estados ; $c->forward (' sistap::View::JSON ');
  • 26. Vistas
    • Predefiniendo una vista
      • sistap.yml
    • Al trabajar con varias vistas, si no se especifica cual usar por defecto, podemos tener problemas.
    --- name: sistap default_view: TT authentication: ...
  • 27. Agregando módulos (Catalyst::Plugin) lib/sistap.pm
      • package sistap;
      • use strict;
      • use warnings;
      • use Catalyst::Runtime '5.70';
      • use Catalyst qw/
      • -Debug
      • ConfigLoader
      • Static::Simple
      • Authentication
      • Authentication::Store::DBIC
      • Authentication::Credential::Password
      • Authorization::Roles
      • Prototype
      • Dumper
      • Session
      • Session::Store::FastMmap
      • Session::State::Cookie
      • /;
      • our $VERSION = '0.01';
      • __PACKAGE__->config ( name => 'sistap',
      • session => { flash_to_stash => 1 },
      • form => { messages => ':es_ES' }
      • );
      • __PACKAGE__->setup ( qw/RequireSSL/ );
      • 1;
      • -Debug
        • Modo verboso en consola cuando se usa servidor de pruebas.
      • ConfigLoader
        • Se usa para cargar información de sistap.yml
      • Static::Simple
        • Para que reconozca archivos estaticos (imagenes, css, js) y no trate despacha las rutas si hay coincidencia.
      • Authentication/Autorization*
        • Autenticación (¿Quién tiene acceso?)
        • Autorización (¿de qué tiene acceso?)
      • Prototype
        • Ejectos integrados de script.aculo.us
      • Dumper
        • uso de Data::Dumper para obtener estructuras completas de data.
      • Session*
        • Manejo de sessiones.
  • 28. Generación de formularios Catalyst::Controller::FormBuilder
  • 29. Generación de formularios
    • Se compone en varios archivos para mayor mantenimiento y abstrabción de conceptos.
      • Detalle de formulario
        • root/forms/nombre/comun.fb
      • Controlador
        • lib/sistap/Controller/nombre.pm
      • Plantilla
        • root/src/nombre/comun.tt
  • 30. FormBuilder en Catalyst (CGI::FormBuilder) Descripción del formulario (root/forms/unesco_subarea/comun.fb)
    • Formato yaml.
    • Usen espacios, no tabs.
    • Definición de elementos y sus atributos.
    • Validaciones (Cliente y Servidor) *
    • Facilmente aplicable a plantillas.
    * la validación absoluta debería aplicarse a nivel de base de datos
      • name: unesco_subarea
      • method: post
      • action: /unesco_subarea/operaciones
      • fields:
      • tOperacion:
      • type: hidden
      • id:
      • id: hdn_id
      • type: hidden
      • id_unesco_area:
      • label : Area
      • type: select
      • id: txt_id_unesco_area
      • disabled : disabled
      • autocomplete: off
      • codigo:
      • id: txt_codigo
      • disabled : disabled
      • autocomplete: off
      • required : 1
      • nombre:
      • id: txt_nombre
      • disabled : disabled
      • autocomplete: off
      • required: 1
      • validate : NAME
  • 31. FormBuilder en Catalyst (CGI::FormBuilder) Controlador (lib/sistap/Controller/unesco_subarea)
      • package sistap::Controller::unesco_subarea;
      • use strict;
      • use warnings;
      • use base 'Catalyst::Controller ::FormBuilder ';
      • ...
      • sub principal : Path('/mantenimiento/unesco_subarea') Form('unesco_subarea/comun') {
      • my ($self, $c) = @_ ;
      • my $form = $self->formbuilder;
      • $form->field( name => 'id_unesco_area',
      • options => [ map {
      • { $_->id_area => $_->nombre }
      • } $c->model(“sistapDB::unesco_area”)->all ]
      • );
      • if ($form->submitted && $form->validate){
      • $c->model(“sistapDB::unesco_subarea”)->create($form->fields) ;
      • }
      • }
  • 32. FormBuilder en Catalyst (CGI::FormBuilder) Plantilla (root/src/unesco_subarea/comun.tt) ó
      • [% FormBuilder.render %]
      • [% FormBuilder.start -%]
      • [% formFuilder.jshead %]
      • <div id=&quot;form&quot;>
      • [% FormBuilder.field.tOperacion.field -%]
      • [% FormBuilder.field.id_institucion.field -%]
      • <table>
      • <tr>
      • <td> [% FormBuilder.field.nombre.label -%]</td>
      • <td> [% FormBuilder.field.nombre.field -%]</td>
      • <td> [% FormBuilder.field.siglas.label -%]</td>
      • <td> [% FormBuilder.field.siglas.field -%]</td>
      • </tr>
      • <tr>
      • <td colspan=”2”><input type=”submit” value=”enviar”> </td>
      • </tr>
      • </table>
      • [% FormBuilder.end -%]
  • 33. Variables de session
  • 34. Uso de sesiones
    • Agregar plugin de session
      • store
        • cookie (la data)
        • bd
        • archivo
      • state
        • url (QueryString)
        • Variable oculta ()
        • cookie (solo id único)
    • Variables de session sólo para el usuario que ejecuta la acción.
      • $c->session->{id} = “hey” ;
      • [% c.session.id %]
      • delete($c->session->{id}) ;
      • $c->session->{id} = undef ;
    • Variable de session para todos los usuarios
      • $c->store_session_data(key,value)
      • $c->store_session_data(“color”,”azul”)
      • $c->get_session_data(key)
      • $c->get_session_data(“color”)
      • $c->delete_session_data(key)
  • 35. uso de Flash (BTW: nada que ver con adobe ™ )
      • Debe estar cargado plugin de sesion ( Catalyst::Plugin::Session )
      • lib/sistap.pm
      • PACKAGE__->config(
        • name => 'sistap',
        • session => {
          • flash_to_stash => 1
        • }
      • );
      • Controlador
      • $c->flash->{error} = “Pagina invalida”
      • Plantilla (TT)
      • [% error %]
  • 36. Autenticación / Autorización
  • 37. Autenticación y autorización --- name: sistap default_view: TT authentication: dbic: # nombre del esquema que contiene la informacion de los usuarios user_class: sistapDB::usuarios # Este es el nombre del campo en la tabla de usuarios, que contiene el nombre del usuario user_field: username # Este es el nombre del campo en la tabla de usuarios, que contiene la clave del usuario password_field: password # Habilitar claves cifradas password_type: hashed # Usamos el algoritmo de cifrado SHA-1 password_hash_type: SHA-1 authorization: dbic: # nombre del esquema que contiene la informacion de los roles del usuario role_class: sistapDB::roles # Este es el nombre del campo en la tabla de de roles, que contiene los diferentes roles role_field: rol # The name of the accessor used to map a role to the users who have this role # nombre de la relación asociada a la tabla de usuarios_roles role_rel: map_user_role # nombre del campo en la tabla de relación usuarios_roles que referencia al usuario (id) user_role_user_field: usuario_id
  • 38. Autenticación y autorización
    • Configuracion: lib/sistap.pm
    • __PACKAGE__->config( name => 'sistap',
      • session => {
    • expires => 2400,
    • storage => '/tmp/session',
    • },
    • );
    • Acciones
      • $c->login($username, $password) ;
      • $c->user_exists ;
      • $c->user->ciUsuario ;
      • $c->check_user_roles('admin') ;
      • $c->logout ;
  • 39. jQuery
  • 40. ¿Qué es jQuery?
    • Framework de JavaScript
    • Selectores de CSS3.
    • Manipulación de eventos.
    • Ajax.
    • Gran cantidad de plugins.
      • Tabs.
      • Menues.
      • Formularios.
      • Dialogos.
      • Drag and Drop.
      • etc ( http://jquery.com/plugins/ )
  • 41. jQuery
      • < script type = &quot;text/javascript&quot; src = &quot;[% c.uri_for('/js/jquery-latest.pack-1_2_1.js') %]&quot; > </ script >
      • < script type = &quot;text/javascript&quot; > jQuery.noConflict () ; </ script >
      • < script type = &quot;text/javascript&quot; >
        • jQuery (function(){
          • // El código a ejecutarse cuando se cargue todo el documento acá
        • }
        • // acá también puede haber código, pero no si se disparará aún cuando
        • // el documento no esté cargado
      • </ script >
  • 42. jQuery: Selectores
    • Básicamente jQuery(“ selector CSS o xpath ”)
    • jQuery ( &quot;#txt_pais&quot; ). val ( jQuery ( &quot;#modal_pais :selected&quot; ). text ())
      • Antes: document.getElementById(“txt_pais”).value = document.getElementById(&quot;modal_pais&quot;).options[document.getElementById(&quot;modal_pais&quot;).selectedIndex].text
    • jQuery(&quot;.jd_menu li ul li ul&quot;).parent().addClass(&quot;flecha_menu&quot;);
      • Antes: Posiblemente usaría un id por cada elemento y sabiendo quién merece la imagen, se la asigno, sino, del lado del servidor.
    • jQuery(&quot;table.cebra tr:even&quot;).addClass(&quot;resaltado&quot;);
      • Antes: Si se construye la tabla de forma dinámica (php, perl, python, etc), controlar el número del registro y asignar la clase correspondiente.
    • jQuery(&quot;input[@type=text]:visible&quot;).eq(0).focus()
      • Antes: Seguro haría lo mismo pero a pie, pasar por todo el fomulario buscando los elementos visibles y luego situarme en el primer elemento.
  • 43. Ajax (ahah)
  • 44. Ajax (ahah)
    • Crear vista de JSON.
      • perl script/sistap_create view JSON JSON
    • La información a enviar como respuesta está en el stash.
      • $c->stash->{salida} = “hey”;
    • jQuery captura los datos.
    • jQuery.getJSON( url , param , function(jsonData){
      • if (jsonData.salida == “hey” ){
        • alert(“fino”);
      • }else{
        • alert(“error al obtener la data”);
      • }
    • })
  • 45. Ajax (JSON)
      • jQuery.getJSON( url , parametros , function(jsonData){ // trabajamos con el resultado... jsonData });
    my $id_pais = $c->req->param ( “pais_id” ); my @estados = $c->model ( &quot;sistapDB::paises&quot; )->find($id_pais)->estados( undef ,{ order_by => ' nombre ' }) ; $c->stash ->{estados} = [ map { { id_estado => $_->id_estado , nombre_estado => $_->nombre } } @estados ]; $c->forward (' sistap::View::JSON ');
      • var param = new Object ();
      • param = { pais_id : 3 } ;
      • jQuery.getJSON( [% c.uri_for('controlador/accion/') %] , param , function(jsonData){
        • if (jsonData.estados){
        • for (i= 0 ; jsonData.estados.lenght ; i++){
        • // tengo jsonData.estados[i].id_estado y jsonData.estados[i].nombre_estado
        • }
        • }else{
          • console.info(“hubo un error al traer la data”);
          • // incluso se puede capturar si se acabó el tiempo de sesión
          • // de usuario según respuesta y se recarga la página.
        • }
      • })
  • 46. jQuery: plugins
    • Tabs
      • http://stilbuero.de/jquery/tabs/
    • menu
      • http://jdsharp.us/jQuery/plugins/jdMenu/
    • Thickbox
      • http://jquery.com/demo/thickbox/
    • Form
      • http://www.malsup.com/jquery/form/
    • Interfaces (interfaces es para para jQuery, lo que script.aculo.us es para prototype)
      • http://interface.eyecon.ro/
    • Muchos mas.
      • http://jquery.com/plugins/
  • 47. jQuery: plugin TABS jQuery(function(){ jQuery('#menu-subvencion').tabs({ fxFade : true , fxSpeed : 'fast' , remote: true }); }) <script type=&quot;text/javascript&quot; src=&quot;[% Catalyst.uri_for('/js/tabs/jquery.history_remote.pack.js') %]&quot;> </script> <script type=&quot;text/javascript&quot; src=&quot;[% Catalyst.uri_for('/js/tabs/jquery.tabs.js') %]&quot;> </script> <link href=&quot;[% Catalyst.uri_for('/js/tabs/jquery.tabs.css') %]&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot; />
      • <div id=&quot;menu-subvencion&quot; >
      • <ul >
      • <li><a href=&quot;[% Catalyst.uri_for('/subvencion/datos_generales') %]&quot;><span>Datos
      • generales</span></a></li>
      • <li><a href=&quot;[% Catalyst.uri_for('/subvencion/resumen') %]&quot; ><span>Resumen</span></a></li>
      • </ul>
      • <div>
  • 48. jQuery: plugin jdMenu
      • $(function(){
      • $('ul.jd_menu').jdMenu();
      • });
    <script type=&quot;text/javascript&quot; src=&quot;[% Catalyst.uri_for('/js/tabs/jquery.dimmension.js') %]&quot;> </script> <script type=&quot;text/javascript&quot; src=&quot;[% Catalyst.uri_for('/js/tabs/jquery.jdMenu.js') %]&quot;> </script> <link href=&quot;[% Catalyst.uri_for('/js/tabs/jdMenu.css') %]&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot; /> <link href=&quot;[% Catalyst.uri_for('/js/tabs/jdMenu.slate.css') %]&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot; />
      • <ul class=&quot;jd_menu jd_menu_slate&quot;>
      • <li> <a class=&quot;accessible&quot;>Item A</a>
      • <ul>
      • <li><a href=&quot;http://www.google.com&quot;>Item 1</a></li>
      • <li><a href=&quot;http://www.google.com&quot;>Item 2</a></li>
      • </ul>
      • </li>
      • <li> <a class=&quot;accessible&quot;>Item B</a> </li>
      • </ul>
  • 49. jQuery: plugin thickbox <script type=&quot;text/javascript&quot; src=&quot;[% Catalyst.uri_for('/js/thickbox/thickbox.js') %]&quot; > </script> <link href=&quot;[% Catalyst.uri_for('/js/thickbox/thickbox.css') %]&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot; />
      • <input type=&quot;button&quot; class=&quot;thickbox&quot; alt=&quot;#TB_inline?height=150&width=700&inlineId=div_modal_institucion&quot;>
      • <div id=&quot;div_modal_institucion&quot; style=&quot;display : none&quot; >
      • <div>
      • <label> Usuario : </label> <input name=”usuario” id=”usuario” />
      • <label> Clave : </label> <input name=”clave” id=”clave” />
      • <input type=”button” value=”Login” id=”login” />
      • <input type=”button” value=”Cancel” id=”cancel” />
      • </div>
      • </div>
  • 50. Depuración
  • 51. Depuración
    • javascript (firebug) : console.info()
  • 52. Depuración
    • Catalyst : $c->log->debug()
  • 53. Depuración
    • DBIC: export DBIC_TRACE=”1=/tmp/salida.txt”
  • 54. Consejos
    • Usar uri_for (en las plantillas y controlador).
      • <a href=”[% c.uri_for('/controlador/accion/param') %]”>Enlace</a>
      • $c->res->redirect( $c->uri_for('/a/b/c') );
    • Usar relaciones en ORM (DBIC).
    • Usar Template Toolkit para generar maestros.
    • Usar Flash + redirect para mensajes a usuario.
    • Usar Ajax solo cuando sea justificado. (No AJfiXiar el sitio)
    • Usar Unicode
      • BD (UTF-8)
      • Servidor web (apache: AddDefaultCharset utf8)
      • Archivo (Usar un editor que lo soporte, como vim )
      • Documento ( html: <meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot; /> )
    • Usar la función “jQuery” en vez de la función anónima ($)
      • jQuery.noConflict()
  • 55. Proyectos libres nacionales desarrollados usando Catalyst ( Que conozco hasta ahora )
    • Debian::Package::HTML
      • http://search.cpan.org/~bureado/Debian-Package-HTML-0.1/lib/Debian/Package/HTML.pm
    • PUBuilder
      • http://blog.bureado.com.ve/?p=307
    • Sist ap:
      • http://sistemas.fsl.fundacite-merida.gob.ve/projects/sistap
    • TEGZ:
      • http://sistemas.fsl.fundacite-merida.gob.ve/projects/tegz
  • 56. ¿Preguntas?
  • 57. Gracias por su atención