SlideShare una empresa de Scribd logo
Javier E. Pérez P. Noviembre 2007 Desarrollo de aplicaciones web usando Catalyst y jQuery
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.
¿Qué es Catalyst? Framework Web escrito usando perl. MVC. Unicode. Servidor de pruebas integrado.
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
Ventajas de su uso
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)
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"); }
Por supuesto, TIMTOWTDI (There Is More Than One Way To Do It)
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
Estructura establecida de los directorios manteniendo un orden.
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;
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'); }
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); }
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 ;
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 ;
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 },   ], );
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 ');
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;
Vistas TTSite Template Toolkit JSON PHP ClearSilver (yahoo, google) ... Predefiniendo una vista.
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
Vistas (Template Toolkit) perl script/sistap_create view TT TT Por defecto, las plantillas se almacenan en root $c->stash->{variable} && [% variable %]
Vistas (JSON) Catalyst::View::JSON perl script/sistap_create view JSON JSON my  @estados = $c->model ( "sistapDB::paises" )->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 ( "sistapDB::paises" )->find($id_pais)->estados()->all ; $c->stash ->{estados} =  @estados  ; $c->forward (' sistap::View::JSON ');
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: ...
Generación de formularios Catalyst::Controller::FormBuilder
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
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. 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
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; my @areas = $c->model(“sistapDB::unesco_area”)->all; my @opciones ; foreach my $area (@areas) { push(@opciones , { $area->id_area => $area->nombre } ) } $form ->field( name => 'id_unesco_area', options => \@opciones  ); if ($form->submitted && $form->validate){ $c->model(“sistapDB::unesco_subarea”)->create($form->fields) ; } }
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 -%]
jQuery
¿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/ )
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 >
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.
Ajax   (ahah)
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”); } })
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 } } })
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/
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>
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>
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>
Depuración
Depuración javascript (firebug) : console.info()
Depuración Catalyst : $c->log->debug()
Depuración DBIC: export DBIC_TRACE=”1=/tmp/salida.txt”
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()
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
¿Preguntas?
Gracias por su atención

Más contenido relacionado

ODP
Desarrollando aplicaciones web usando Catalyst y jQuery
ODP
Desarrollo de aplicaciones web usando Catalyst y jQuery
PDF
Cómo domar SonataAdminBundle
PDF
Symfony parte 15 Consultas y Migración
DOCX
Informe grupal f_arinango_ cuenca
PDF
Api De Google Calendar
PDF
Ejemplos de php_mysql
PDF
WordCamp Cantabria - Código mantenible con WordPress
Desarrollando aplicaciones web usando Catalyst y jQuery
Desarrollo de aplicaciones web usando Catalyst y jQuery
Cómo domar SonataAdminBundle
Symfony parte 15 Consultas y Migración
Informe grupal f_arinango_ cuenca
Api De Google Calendar
Ejemplos de php_mysql
WordCamp Cantabria - Código mantenible con WordPress

La actualidad más candente (20)

PDF
deSymfony 2013 - Creando aplicaciones web desde otro ángulo con Symfony y A...
DOC
Php
PDF
Deployer PHP. Presentación para #PHPSevilla
PDF
Cloud Computing: las nuevas Capas de Persistencia
PPTX
Tarea 2 y_3
RTF
Wp config.php
PDF
Desymfony 2011 - Twig
PPT
tutorial de slide.com
PDF
Zen AJAX - Programador PHP
PDF
Introducción a recaptcha 3.0
PDF
Desymfony 2011 - Introducción a Symfony2
PDF
Curso php y_mysql
ODP
Tutorial3 Desymfony - La Vista. Twig
PDF
Código mantenible, en Wordpress.
PDF
Customizer: configurando un sitio en tiempo real
PDF
Introducción a PHP - Programador PHP - UGR
PDF
Composer: Gestionando dependencias en PHP
PPTX
Reactividad en Angular, React y VueJS
DOCX
Php excel
DOCX
POO en php, clases
deSymfony 2013 - Creando aplicaciones web desde otro ángulo con Symfony y A...
Php
Deployer PHP. Presentación para #PHPSevilla
Cloud Computing: las nuevas Capas de Persistencia
Tarea 2 y_3
Wp config.php
Desymfony 2011 - Twig
tutorial de slide.com
Zen AJAX - Programador PHP
Introducción a recaptcha 3.0
Desymfony 2011 - Introducción a Symfony2
Curso php y_mysql
Tutorial3 Desymfony - La Vista. Twig
Código mantenible, en Wordpress.
Customizer: configurando un sitio en tiempo real
Introducción a PHP - Programador PHP - UGR
Composer: Gestionando dependencias en PHP
Reactividad en Angular, React y VueJS
Php excel
POO en php, clases
Publicidad

Similar a Desarrollo de aplicaciones web usando Catalyst y jQuery (20)

PPTX
Germán Peraferrer: Cormo Framework
PPTX
Cormo Framework
PPT
Descubriendo Ruby On Rails (Desarrollo Agil De Aplicaciones Web)
PPT
Descubriendo Ruby on Rails (Desarrollo Agil de Aplicaciones Web)
PPTX
Frameworrk
PDF
Catalyst: Framework para el desarrollo de aplicaciones Web
ODP
Introducción a Kohana Framework
DOCX
Manual tecnico umasoft
PPTX
Interoperabilidad-iso-ogc-w3c-ietf
PPTX
Interoperabilidad-iso-ogc-w3c-ietf
ODP
Web framework ligeros y micros en java barcamp 2014
ODP
GeoEtiquetas (2das Jornadas Latinoamérica y Caribe gvSIG)
PDF
Un poco más allá con grails. PrimerViernes
PPT
Kumbia PHP Framework - Inicios, Presente y Futuro
PDF
Introduccion al Akelos Php Framework
PDF
Primeros pasos con neo4j
PDF
Grails: Framework para el desarrollo de aplicaciones Web No 2
PPTX
Desarrollo busmanagger
PPTX
Framework Catalyst
PPTX
Greenstone: migrando hacia una biblioteca digital 3.0
Germán Peraferrer: Cormo Framework
Cormo Framework
Descubriendo Ruby On Rails (Desarrollo Agil De Aplicaciones Web)
Descubriendo Ruby on Rails (Desarrollo Agil de Aplicaciones Web)
Frameworrk
Catalyst: Framework para el desarrollo de aplicaciones Web
Introducción a Kohana Framework
Manual tecnico umasoft
Interoperabilidad-iso-ogc-w3c-ietf
Interoperabilidad-iso-ogc-w3c-ietf
Web framework ligeros y micros en java barcamp 2014
GeoEtiquetas (2das Jornadas Latinoamérica y Caribe gvSIG)
Un poco más allá con grails. PrimerViernes
Kumbia PHP Framework - Inicios, Presente y Futuro
Introduccion al Akelos Php Framework
Primeros pasos con neo4j
Grails: Framework para el desarrollo de aplicaciones Web No 2
Desarrollo busmanagger
Framework Catalyst
Greenstone: migrando hacia una biblioteca digital 3.0
Publicidad

Último (20)

PDF
Plantilla para Diseño de Narrativas Transmedia.pdf
PDF
Aristoteles-y-su-forma-de-entender-el-conocimiento-y-las-personas.pdf
PDF
programa-de-estudios-2011-guc3ada-para-el-maestro-secundarias-tecnicas-tecnol...
PPT
Que son las redes de computadores y sus partes
DOCX
Trabajo colaborativo Grupo #2.docxmmuhhlk
PPTX
REDES INFORMATICAS REDES INFORMATICAS.pptx
PDF
Temas y subtemas de las fichas 1 y 2.pdf
PDF
Conceptos básicos de programación tecnología.pdf
PDF
Estrategia de apoyo tecnología grado 9-3
PPTX
RAP02 - TECNICO SISTEMAS TELEINFORMATICOS.pptx
PPTX
Administración se srevidores de apliaciones
PPT
introduccion a las_web en el 2025_mejoras.ppt
PPTX
IA de Cine - Como MuleSoft y los Agentes estan redefiniendo la realidad
PPTX
Yogurt de tocosh (1).pptx preparacion receta
PPTX
historia_web de la creacion de un navegador_presentacion.pptx
DOCX
Las nuevas tecnologías en la salud - enfermería técnica.
PDF
Influencia-del-uso-de-redes-sociales.pdf
PDF
MÓDULO DE CALOR DE GRADO DE MEDIO DE FORMACIÓN PROFESIONAL
PPTX
Introduccion a servidores de Aplicaciones (1).pptx
PDF
Estrategia de apoyo tecnología miguel angel solis
Plantilla para Diseño de Narrativas Transmedia.pdf
Aristoteles-y-su-forma-de-entender-el-conocimiento-y-las-personas.pdf
programa-de-estudios-2011-guc3ada-para-el-maestro-secundarias-tecnicas-tecnol...
Que son las redes de computadores y sus partes
Trabajo colaborativo Grupo #2.docxmmuhhlk
REDES INFORMATICAS REDES INFORMATICAS.pptx
Temas y subtemas de las fichas 1 y 2.pdf
Conceptos básicos de programación tecnología.pdf
Estrategia de apoyo tecnología grado 9-3
RAP02 - TECNICO SISTEMAS TELEINFORMATICOS.pptx
Administración se srevidores de apliaciones
introduccion a las_web en el 2025_mejoras.ppt
IA de Cine - Como MuleSoft y los Agentes estan redefiniendo la realidad
Yogurt de tocosh (1).pptx preparacion receta
historia_web de la creacion de un navegador_presentacion.pptx
Las nuevas tecnologías en la salud - enfermería técnica.
Influencia-del-uso-de-redes-sociales.pdf
MÓDULO DE CALOR DE GRADO DE MEDIO DE FORMACIÓN PROFESIONAL
Introduccion a servidores de Aplicaciones (1).pptx
Estrategia de apoyo tecnología miguel angel solis

Desarrollo de aplicaciones web usando Catalyst y jQuery

  • 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
  • 6. 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)
  • 7. 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(&quot;root/reporte.pdf&quot;,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(&quot;/archivo.pdf&quot;); }
  • 8. Por supuesto, TIMTOWTDI (There Is More Than One Way To Do It)
  • 9. 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
  • 10. Estructura establecida de los directorios manteniendo un orden.
  • 11. 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;
  • 12. 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'); }
  • 13. 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 = &quot;Esta pantalla muestra la revision: &quot; . $c->stash->{var2} ; $salida .= &quot; de la pagina: &quot; . $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 = &quot;Esta pantalla muestra la revision: &quot; . $c->stash->{var2} ; $salida .= &quot; de la pagina: &quot; . $c->stash->{var1} ; $c->res->body($salida); }
  • 14. 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 ;
  • 15. 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 ;
  • 16. 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 }, ], );
  • 17. 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 ');
  • 18. 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(&quot;codigo&quot;), 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;
  • 19. Vistas TTSite Template Toolkit JSON PHP ClearSilver (yahoo, google) ... Predefiniendo una vista.
  • 20. 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
  • 21. Vistas (Template Toolkit) perl script/sistap_create view TT TT Por defecto, las plantillas se almacenan en root $c->stash->{variable} && [% variable %]
  • 22. 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 ');
  • 23. 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: ...
  • 24. Generación de formularios Catalyst::Controller::FormBuilder
  • 25. 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
  • 26. 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. 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
  • 27. 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; my @areas = $c->model(“sistapDB::unesco_area”)->all; my @opciones ; foreach my $area (@areas) { push(@opciones , { $area->id_area => $area->nombre } ) } $form ->field( name => 'id_unesco_area', options => \@opciones ); if ($form->submitted && $form->validate){ $c->model(“sistapDB::unesco_subarea”)->create($form->fields) ; } }
  • 28. 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 -%]
  • 30. ¿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/ )
  • 31. 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 >
  • 32. 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.
  • 33. Ajax (ahah)
  • 34. 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”); } })
  • 35. 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 } } })
  • 36. 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/
  • 37. 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>
  • 38. 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>
  • 39. 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>
  • 42. Depuración Catalyst : $c->log->debug()
  • 43. Depuración DBIC: export DBIC_TRACE=”1=/tmp/salida.txt”
  • 44. 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()
  • 45. 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
  • 47. Gracias por su atención