Está en la página 1de 25

Tutorial Customsite framework Creating a component step by step (Spanish) customsite framework version 0.3.

11 alpha

CARLOS RODRGUEZ DEL MORAL a 2 de Noviembre de 2012 Creative Commons Attribution-No Derivatives (CC BY-ND) https://sourceforge.net/projects/customsite/

ndice

1.- Resumen de lo que necesitamos para crear un componente con customsite framework. 2.- Primer paso: La estructura bsica de un componente para customsite framework. 3.- Segundo paso: Comprendiendo las clases necesarias para crear un componente y otras clases que usa customsite framework para trabajar con los componentes a nivel interno. 3.1- backend/Components 3.2- components/Component 3.3- lib/HtmlFormatOutput 4.- Tercer paso: Componente HelloWorld. 4.1- Creando metadata para componente con info.xml 4.2- Creando la clase principal del componente 5.- Cuarto paso: Mostrando el componente en la vista deseada. 6.- Otras cosas a tener en cuenta sobre los componentes en customsite framework. 6.1- Aadiendo scripts en el header 6.2- Aadiendo servicios al componente 7.- Creando un componente avanzado paso a paso.

1.- Resumen de lo que necesitamos para crear un componente con customsite framework. Para comenzar a crear un componente en customsite framework debemos entender primero una serie de clases y mecanismos bsicos que nos permitirn construir nuestro componente. Para ello, hay que comprender primero el funcionamiento bsico de customsite framework. Vamos a resumir brevemente lo que ocurre cuando un usuario escribe una url en el navegador y lo que pasa en el servidor con customsite framework. Supongamos que un usuario escribe en el navegador la url http://localhost/helloworld . Esto es lo que ocurre: 1. La clase encargada de mapear las url pasadas por el navegador con los objetos descritos en router.xml se encarga de llamar al objeto request correspondiente para esa url. (Inicialmente gluephp.com y la clase gluephp desarrollada por Joe Topjian me inspiraron a la hora de crear el mapeador de urls) 2. El objeto request hace sus labores y llama al objeto Controlador y este a su vez prepara la vista y el template. (La vista no debe confundirse con el template, lo que hace principalmente la vista es organizar el buffer de salida en las secciones estandares header, content, sidebar, footer entre otras labores importantes, de hecho, desde el Controlador enganchamos nuestros componentes a la vista a travs del objeto View (vista), el cual est contenido dentro del objeto Controlador y accedemos a esta usando $this->_view. Tambin trabajaremos el template desde el controlador, entonces pasamos el template a la vista a travs del mtodo setTemplate para luego mostrarlo con su layout correspondiente a travs del mtodo showLayout, existe otra manera mas simple usando el mtodo de la vista setViewTemplate.) 3. Desde el mismo objeto Controlador $this->_view>addComponent( 'sidebar', new HelloWorld( $frmt ) ) Ahora que ya entendemos el funcionamiento bsico podemos resumir qu necesitamos para construir un componente: El componente con sus clases, scripts y metadata dentro de una carpeta nombrada con el nombre del componente en minsculas, esta carpeta estar a su vez dentro de la carpeta components (components/helloworld/ ) Esto sera para un componente llamado HelloWorld.

Una pgina donde mostrarlo, normalmente engancharemos el componente desde el Controlador a travs del mtodo addComponent de la vista $this->_view->addComponent( 'sidebar', new HelloWorld( $frmt ) ) Todo componente visual tiene un formato que sigue las reglas de lib/HtmlFormatOutput, estas lo que hacen es permitir formatear el container html del componente en la salida del navegador, pero esto ya lo veremos mas adelante, aunque adelanto que es muy sencillo. En nuestro caso, el componente HelloWorld es un componente visual, por lo que extiende la clase de la siguiente manera: class HelloWorld extends HtmlFormatOutput.

2.- Primer paso: La estructura bsica de un componente para customsite framework. La estructura bsica de un componente est compuesta de la siguiente manera: Un directorio con el nombre de componente en minsculas que contiene todo los archivos del componente, ya sea cdigo php, javascript o xml entre otros que fueran necesarios. Este directorio se copia siempre dentro de la carpeta components, la cual forma parte de customsite framework. Ejemplo: components/helloworld/HelloWorld.php components/helloworld/info.xml Existirn components que aadan scripts e incluso servicios: components/theweather/js/script.js components/theweather/js/services/service_name.js (Este tipo de componentes mas complejos ya los veremos a medida que vayamos avanzando en nuestro tutorial). Los dos ficheros principales de todo componente son: 1. info.xml (Siempre es el mismo) 2. NombreComponente.php (En nuestro ejemplo HelloWorld.php).

Contenido de info.xml: <?xml version="1.0" encoding="UTF-8"?> <component> <name>HelloWorld</name> <class>HelloWorld.php</class> <author>charlyasap</author> <contact>lpgc.carlos@gmail.com</contact> <site>http://dev.afilweb.com</site> <description>Hello World!</description> </component>

Contenido de HelloWorld.php: class HelloWorld extends HtmlFormatOutput { private $_message; public function __construct($frmt = '') { $this->_message = 'Hello World!'; if ( isset( $frmt ) && is_array( $frmt ) ) { $this->format($frmt); } } public function format(Array $frmt) { $this->set_format_start( $frmt['start'] ); $this->set_format_end( $frmt['end'] ); $this->buffer .= $this->frmt_start;; } public function flush() { $this->buffer .= $this->_message; parent::flush(); } public function getBuffer() { $this->buffer .= $this->_message; return parent::getBuffer(); } }

3.- Segundo paso: Comprendiendo las clases necesarias para crear un componente y otras clases que usa customsite framework para trabajar con los componentes a nivel interno. Existe 1 clase que debemos conocer bien, esta es HtmlFormatOutput y se encuentra en la carpeta lib de customsite framework. Existen 2 clases de uso interno que miraremos por encima para tener un conocimiento mas profundo del sistema, pero no es necesario comprender estas para crear componentes. Estas clases son Components y Component, la primera forma parte del backend y es parte de customsite framework y la segunda forma parte de Components y tambin es parte de la base de customsite framework. Es decir, son clases que vienen con el framework y que estn en esas carpetas. 3.1- backend/Components La clase Components es una clase del backend y como clase de backend es la encargada de manejar los datos sobre componentes que residen en la base de datos. Esta clase adems incluye un mtodo que nos devolver aquellos componentes activos. Esta es una clase interna as que slo la usaremos de forma explcita en raras ocasiones. 3.2- components/Component La clase Component (en singular) es una clase interna del framework que se carga automticamente cuando se inicia el framework, esta clase crea una lista de todos los componentes residentes en la carpeta components de customsite framework y los guarda en un array interno, este array interno contiene toda la informacin de cada componente, es decir, la clase llama desde su constructor al mtodo recursivo getInfoFromComponents, este mtodo lo que hace es extraer toda la informacin de cada fichero info.xml residente en la carpeta de cada componente dentro de la carpeta components, toda esa informacin es guardada en el array interno de la clase Component. La clase ofrece algunos mtodos que son necesarios para el funcionamiento del sistema, estos son los siguientes:

public function loadService( $service_name ) : Este mtodo lo que hace es buscar un servicio especfico dentro de un componente y devolver una string con la ruta para que pueda ser cargado. Los nombres de servicios deben ser nombres nicos ya que cada servicio tendr una url asociada. Esto lo veremos mas adelante. public function loadComponent( $component_name ): Este mtodo nos devuelve una string con la ruta al fichero principal del componente para que podamos cargarlo. Este mtodo es utilizado implcitamente por el boostrap de customsite framework. public function getFromComponent( $component_name, $attribute_name ) : Devuelve un atributo especfico que haya sido definido en el fichero info.xml para un componente. 3.3- lib/HtmlFormatOutput La clase HtmlFormatOutput es una clase abstracta que debe ser extendida para todos aquellos componentes que sean visuales, bsicamente lo que ofrece HtmlFormatOutput es una interfaz con la que los componentes puedan ser preparados para ser renderizados en el navegador De esta forma podremos vestir los componentes con estilos y cdigo html a la hora de inicializar el componente de forma implcita desde su constructor, que es la manera mas recomendada. Los dos mtodos principales con los que debemos familiarizarnos son set_format_start y set_format_end. Existen otros dos mtodos que debemos implementar para preparar el componente para cuando este sea insertado en la vista con addComponent, estos mtodos son flush y getBuffer. Bsicamente flush imprime y getBuffer devuelve el buffer en una string. (Para comprenderlo bien es mejor mirar el cdigo del componente HelloWorld en la pgina 5 de este turorial.) Desde el Controlador: $frmt = array( 'start' => '<strong style="color:green">', 'end' => '</strong>' ); $this->_view->addComponent( 'sidebar', new HelloWorld( $frmt ) ); Componente: set_format_start: $this->set_format_start( $frmt['start'] ); set_format_end: $this->set_format_end( $frmt['end'] );

Analizando el componente HelloWorld: format($frmt) : Este mtodo se llama desde el constructor. (Recordemos que desde el Controlador creamos el componente y lo pasamos a la vista filtrando en donde queremos mostrarlo, por ejemplo en sidebar. El argumento al crear el componente ser el formato $frmt con su html/estilo) public function format(Array $frmt) { $this->set_format_start( $frmt['start'] ); $this->set_format_end( $frmt['end'] ); /* Esto es importante, si nos fijamos, trabajamos con un bufer para la salida, as que despus de inicializar la clase con el formato deseado inicializamos el buffer con el formato de inicio. */ $this->buffer .= $this->frmt_start; /* Ya apreciaremos cuando miremos todo el componente que en ninguna parte hacemos referencia al formato de finalizacin, esto es porque lo hace implcitamente la clase padre a la hora de mostrar o devolver el buffer */ } Flush(): public function flush() { /* Sobre escribimos el mtodo flush para aadir el contenido al buffer justo antes de finalizar llamando a flush en el objeto padre, que es quien aade al buffer implcitamente el formato de finalizacin */ $this->buffer .= $this->_message; /* en format() llenamos esta variable con $this->set_format_end( $frmt['end'] ); */ parent::flush(); /* $buff .= $this->frmt_end; */ } getBuffer(): public function getBuffer() { /* El mecanismo que explicamos para flush() es el mismo aqu , solo que en este caso lo hace getBuffer*/ $this->buffer .= $this->_message; return parent::getBuffer(); }

4.- Tercer paso: Componente HelloWorld. En este paso comenzaremos creando el componente HelloWorld paso a paso, adems, lo haremos de tal manera que aquellos que no hayan tenido un primer contacto con customsite framework aprendan a crear una pgina bsica para luego mostrar nuestro componente. Es decir, antes de crear el componente crearemos una pgina y su plantilla (template), entonces crearemos el componente y finalmente lo inicializaremos desde el Controlador de la pgina creada. Los pasos a seguir para crear una pgina son los siguientes: Utilizar slo el script rvc(Request-View-Controller) ya que no nos interesa crear ningn modelo para este ejemplo. scripts/rvc/rvc2class.php help (para ayuda). Para crear las clases Request, Controller y View de nuestra pgina ejecutamos el siguiente comando desde la raiz de customsite framework: (*) Antes de ejecutar el comando debemos asegurarnos de que est presente en nuestro sistema php5-cli. (Para instalarlo en Linux ubuntu: sudo apt-get install php5-cli) $ scripts/rvc/rvc2class.php --name HelloWorld --output backend/ Despus de haber ejecutado nuestro comando, el script habr generado el esquelo rvc creando la siguientes clases en el directorio backend: HelloworldRequest.php HelloworldController.php HelloworldView.php A partir de ahora todo lo que tenemos que hacer es editarlas para realizar los cambios necesarios, puesto que no necesitamos ninguna configuracin especial tan solo editaremos la clase backend/HelloworldController.php y configuraremos el template, nuestro componente y la vista desde esta clase controladora. Para crear el componente crearemos una carpeta nueva con el nombre en minsculas de nuestro componente, en nuestro caso

la carpeta se llamar helloworld. A continuacin copiaremos la carpeta dentro de la carpeta components de customsite framework y ya podemos crear el componente HelloWorld. 4.1- Creando metadata para componente con info.xml Comenzamos creando la descripcin de nuestro componente en el fichero meta info.xml. Este fichero contiene la informacin de nuestro componente en formato xml simple. Ya habamos visto anteriormente el contenido de info.xml, ahora veremos con mas detalle cada uno de sus componentes. 1.- Creamos info.xml dentro de la carpeta helloworld. <?xml version="1.0" encoding="UTF-8"?> <component> <name>HelloWorld</name> <class>HelloWorld.php</class> <author>charlyasap</author> <contact>lpgc.carlos@gmail.com</contact> <site>http://dev.afilweb.com</site> <description>Hello World!</description> </component>

Los tres tags principales de un componente bsico: <name>HelloWorld</name>: Usamos el tag name para darle un nombre oficial a nuestro componente, normalmente le damos el mismo que la clase principal, pero esto podra ser diferente si el programador lo decide. <class>HelloWorld.php</class>: El tag class para designar un nombre de clase para nuestro componente, normalmente se usa el mismo nombre que name, pero esto podra no ser as en determinadas situaciones si as lo decide el programador. <description>Hello World!</description>: El tag description para dar una descripcin a nuestro componente, esta descripcin ser utilizada por otras aplicaciones como un panel de administracin para un blog.

4.2- Creando la clase principal del componente Por fin hemos llegado al punto en donde creamos la clase de nuestro componente. Lo que vamos a hacer a continuacin es crear la clase y explicar brevemente como llamarla desde el controlador, pues los detalles ya los vimos en puntos anteriores, adems veremos tambin como crear la plantilla de la pgina y como usarla desde el controlador. Hay que sealar que la creacin de la pgina nada tiene que ver con la creacin de un componente, lo que hemos hecho es un ejercicio completo de creacin de pgina bsica + componente. As cualquier persona puede entender este tutorial. Manos a la obra, comenzamos con la clase del Componente: Creamos el fichero HelloWorld.php en nuestro editor favorito y escribimos el siguiente cdigo, todo esto fue cubierto en puntos anteriores. Como recordatorio un componente visual extiende de la clase abstracta HtmlFormatOutput y sobre escribe 2 mtodos principales, la clase tiene un buffer de salida que controla todo y delega a los mtodos padre, estos son los encargados de terminar la operacin. (Si sigue teniendo dudas vaya atrs y consulte los detalles de todo esto en la pgina 8). 2.- Creamos HelloWorld.php dentro del directorio helloworld:
class HelloWorld extends HtmlFormatOutput { private $_message; public function __construct($frmt = '') { $this->_message = 'Hello World!'; if ( isset( $frmt ) && is_array( $frmt ) ) { $this->format($frmt); } } public function format(Array $frmt) { $this->set_format_start( $frmt['start'] ); $this->set_format_end( $frmt['end'] ); $this->buffer .= $this->frmt_start; } public function flush() { $this->buffer .= $this->_message; parent::flush(); } public function getBuffer() { $this->buffer .= $this->_message; return parent::getBuffer(); } }

Ahora que ya tenemos nuestro componente creado y para finalizar el tercer paso, abrimos backend/HelloWorldController.php y debajo de la linea que dice as if ($this->_view instanceof View ) escribimos las siguientes lineas de cdigo que definen el formato del componente , crean el componente y lo insertan en la vista, en este ejemplo en el sidebar:
$frmt = array( 'start' => '<strong style="color:green">', 'end' =>'</strong>' ); $this->_view->addComponent( 'sidebar', new HelloWorld( $frmt ) );

Ahora ya tenemos nuestro componente visible en nuestra pgina, todo lo que tenemos que hacer es crear nuestro template por defecto, para ello customsite framework tiene un mecanismo en el que hace referencia a un template por defecto, este podemos cambiarlo, pero en nuestro caso lo usaremos, el nombre de un template por defecto es el nombre de la clase sin el prefijo, esto es para el fichero HelloWorld_Controller ( clase HelloWorldController) ser usado HelloWorld_Template, pero este no es creado en disco por defecto, as que es necesario crearlo, as que abrimos nuestro editor y creamos HelloWorld_Template.html y ponemos lo que queramos dentro. El ltimo detalle que no debemos pasar por alto es que nuestra pgina necesita una url especfica ya que es una pgina que hemos creado a parte de forma individual, por ello, abrimos router.xml y lo editamos aadiendo lo siguiente: <map> <expr>/helloworld</epxr> <className>HelloWorld_Request</className> </map> En la versin actual de customsite framework (0.3.11) tendremos que activar el componente de forma manual en la base de datos porque an no tenemos desarrollado un panel de control que los active o desactive. Para ello debemos insertar HelloWorld en la base de datos teniendo en cuenta las siguientes columnas de la tabla components: (Por defecto este componente HelloWorld viene instalado y activado como ejemplo).
+++++++ |Field|Type|Null|Key|Default|Extra| +++++++ |ID|int(10)unsigned|NO|PRI|NULL|auto_increment| |name|varchar(64)|NO||NULL|| |path|varchar(250)|NO||NULL|| |status|int(1)|NO||NULL|| +++++++

Slo nos falta una cosa que no ocurre automticamente en la versin 0.3.11 alpha de customsite framework, por ahora hay que introducir manualmente los includes a las clases de una pgina nueva que hayamos creado en el index.php, as que abrimos index.php y lo editamos. index.php require_once 'backend/HelloworldRequest.php'; require_once 'backend/HelloworldController.php'; Si te has fijado, al utilizar el script rvc2class.php para generar nuestras clases le dimos un output de backend y no descartamos la clase vista, as que nos meti tambin la clase vista en backend, as que tendremos que moverla al directorio frontend para tenerlo todo mas ordenado. require_once 'fronend/HelloworldView.php'; Esto podramos haberlo hecho de la siguiente manera a la hora de generar las clases con el script: $scripts/rvc/rvc2class.phpnameHelloWorldoutput backend/discardview $scripts/rvc/rvc2class.phpnameHelloWorldoutput frontend/drequest,controller(elespacioentre nombresesimportantetraslacoma) *(Nocopieypegueelcdigoporquelascomillasylos guionestendrnunformatodiferentequeenelterminal ydarerror).

Despus de todo, intentamos ver la pgina escribiendo la url en nuestro navegador: http://localhost/helloworld Pero no carga, entonces nos vamos al log de errores de nuestro apache, en mi caso /var/log/apache2/error.log y vemos cual es el problema: [error][client127.0.0.1]PHPFatalerror:Calltoa memberfunctionaddBuffer()onanonobjectin /var/www/backend/HelloworldController.phponline38 Parece que hemos olvidado referenciar el objeto $template en nuestro controlador (aadimos global $template y ahora funciona). Al refrescar el

navegador nos encontraremos con un segundo error, este tiene que ver con la nomenclatura, esto es debido a que el script cuando le pasamos un nombre compuesto por dos o mas letras solo pone en mayscula la primera letra, as que nos devuelve el siguiente error: [FriNov0217:42:242012][error][client127.0.0.1]PHP Warning: file_get_contents(/var/www/frontend/templates//Helloworld _Template.html):failed toopenstream:Nosuchfileordirectoryin /var/www/lib/customtemplate/CustomTemplate.phponline67 Para corregirlo tan solo tenemos que renombrar HelloWorld_Template.htmlporHelloworld_Template.html Contenidodeltemplate: <strong>Thisisthecontent</strong>

Ahora ya tenemos nuestro primer componente funcionado en una pgina que hemos creado especficamente para mostrar nuestro componente. Hemos aprendido a utilizar el script rvc para crear una pgina, tambin hemos aprendido a asignar una url a esta pgina, a usar el template por defecto y a asignar el componente a una vista. Ya hemos aprendido todo lo que hace falta para hacer componentes en customsite framework. A continuacin profundizaremos un poco mas y finalmente desarrollaremos un componente avanzado. En la versin 3.0.11 alpha con la que estamos trabajando el script rvc no aade todava a la vista la llamada al mtodo showComponents con el filtro, por ello, hasta que tengamos la versin 3.1 alhpa tendremos que editar la vista y hacerlo a mano, entonces editamos la vista en frontend/HelloworldView.php y editamos el siguiente bloque como sigue, fijarse que deben aadir lo que est en negrita tal cual (@todo Esto debe ser generado en la versin 3.1 automticamente): public function sidebar($template_buffer) { $this->_sidebar = $template_buffer; $this->showComponents('sidebar'); return $template_buffer; } Hello World! (Finalmente tenemos todo completado).

5.- Cuarto paso: Mostrando el componente en la vista deseada. En este punto veremos en mas detalle como mostrar el componente en una vista determinada y qu opciones por defecto tenemos. En esta versin de customsite framework podemos insertar el componente en la vista de forma directa escribiendo cdigo en la seccin de la vista que nos interese o insertando el componente desde el controlador a travs del mtodo de la vista addComponent: addComponent('header', $component); addComponent('content', $component); addComponent('sidebar',$component); addComponent('footer',$component);

Esto nos permite insertar componentes en las diferentes partes del layout, el cual est bien descrito en el controlador. En versiones posteriores de customsite framework ser posible insertar componentes antes o despus del contenido del layout. Por ejemplo: addComponent('footer',$component, true); // inserta antes addComponent('footer',$component, false); //false (despus) addComponent('footer',$component); //false (despus) Otra caracterstica que estar disponible en versiones posteriores de customsite framework ser un mecanismo de tags, de esta manera podremos insertar directamente el componente usando un tag, aunque esto es posible hacerlo actualmente haciendo uso del template, por ejemplo, en vez de usar addComponent para asignarlo al layout de una vista podremos obtener su buffer con getBuffer e insertar el buffer al template utilizando el mtodo de template setTemplateValue. Por qu debemos habilitar un mecanismo de tags para futuras versiones de customsite framework si ya podemos hacerlo usando templates?. -La respuesta es simple, en un entorno dinmico en el que el usuario inserta contenido, por ejemplo un artculo, es posible que el usuario cree un tag y desee que ese tag sea el punto de insercin de un componente visual (widget). Hasta ahora es el programador quien tiene control de esto, para el usuario necesitamos el mecanismo de tags.

6.- Otras cosas a tener en cuenta sobre los componentes en customsite framework. Este punto merece un tutorial a parte por ello vamos a especificar de la forma mas escueta posible las funcionalidades para aadir scripts y estilos al header desde un componente y los servicios de forma muy superficial. 6.1- Aadiendo scripts en el header Si abrimos una versin de customsite framework desde la 0.3.11 en adelante de podremos ver en el componente ImageUploader en la carpeta imageuploader, la clase ImageUploader.php:
/*fragmentodelaclaseImageUploaderdecustomsiteframework*/ /* *customsiteframeworkmaybefreelydistributedundertheextended3clause BSDlicense *Foralldetailsanddocumentation: *https://sourceforge.net/projects/customsite/ * *CreatedbyCarlosRodriguezdelMoralon2012. * *Copyright(c)2012CarlosRodriguezdelMoral *Allrightsreserved. */ classImageUploaderextendsHtmlFormatOutput{ private$_uploader; publicfunction__construct(){ $scripts=array(); $scripts[]=newScript('javascript', Config::$componentsfolder. '/imageuploader/js/services/upload_service.js'); $scripts[]=newScript('javascript', Config::$componentsfolder.'/imageuploader/js/articleeditor.js'); global$script_collection; foreach($scriptsas$script_object){ $script_collection>addScript($script_object); } }

Si nos fijamos en el cdigo resaltado, veremos como desde el constructor de nuestro componente estamos enganchando nuestros scripts, estos scripts sern la parte cliente de nuestros servicios. 6.2- Aadiendo servicios al componente Para aadir servicios al componente debemos hacerlo en la raiz de la carpeta del componente, debemos aadirlos a travs del archivo info.xml y entonces ya tenemos todo listo. Este punto es bastante avanzado as que lo

dejaremos para un tutorial especfico sobre esto componentes que presten servicios, ya sean visuales o no visuales. 7.- Creando un componente avanzado paso a paso. En este ltimo punto vamos a crear paso a paso un componente algo mas elaborado que el que hemos visto anteriormente. Crearemos un componente que nos sirva para paginar resultados. El componente estar diseado para funcionar en modo esttico, es decir, no utilizar ningn servicio ni refrescar el contenido en la misma pgina. Quiz mas adelante sea una buena idea preparar un paginador dinmico para otro tipo de aplicaciones como paneles de administracin, pero en nuestro caso nos interesa tenerlo esttico para que les sea mas fcil a los buscadores recorrer su contenido. Este componente lo estoy creando a 3 de noviembre de 2012, al mismo tiempo que escribo este punto del tutorial, el componente es parte de la base de customsite framework ya que es una pieza comn que podemos reutilizar en cualquier proyecto. Para comenzar nos situamos en la carpeta de componentes (components) y creamos la carpeta de nuestro nuevo componente a la que daremos el nombre paginator. A pesar de que nuestro paginador ser un componente esttico lo haremos de tal manera que podamos elegir un tipo diferente de paginador segn nuestras necesidades. Para ello, tenemos que nuestro paginador tendr un aspecto diferente y un comportamiento diferente segn nuestra necesidad. Existen tres tipos de de paginadores que son genricos y que sern los que vamos a implementar: Paginador con nmeros (PaginatorNumbered) [1] [2] [3] [4] [5] ... A este paginador le podremos indicar un lmite mximo de pginas de seleccin (opcional), por ejemplo: Si el lmite es 10 tendremos [1] hasta [10] Si el lmite es 3 tendremos por ejemplo [5][6][7] Adems, tendremos otra opcin (opcional) en la que indicaremos si deseamos mostrar un enlace a Inicio y otro a Siguiente > . Paginador con letras( PaginatorAZ)

[A][B][C]...[Z] [a][b][c]...[z] Este paginador ser simple y aceptar tan solo una opcin (opcional) para indicar si queremos maysculas o minsculas. Paginador Simple; atrs, adelante (PaginatorSimple) Este ser el paginador mas simple de cara al usuario, lo que har ser mostrar Siguiente > y en su caso < Atrs.

Clases necesarias para nuestro componente: iPaginator Paginator PaginatorNumbered PaginatorAZ PaginatorSimple

La interfaz iPaginator.php:
/* *customsiteframeworkmaybefreelydistributedundertheextended3clause BSDlicense *Foralldetailsanddocumentation: *https://sourceforge.net/projects/customsite/ * *CreatedbyCarlosRodriguezdelMoralon2012. * *Copyright(c)2012CarlosRodriguezdelMoral *Allrightsreserved. */ /*Enestaversionsolousaremossetresultsnumber,peroenunaimplementacin futuratendremosqueimplementarestosotrosmtodosjuntoconotrainterfaz paracrearunnuevocomponentedepaginacindinmicaparaaplicacionescomoel paneldecontroldeladmin*/ interfaceiPaginator{ publicfunctionprev(); publicfunctionnext(); publicfunctiongotopage($offset);//alphanum publicfunctionupdate(); publicfunctionsetresultsnumber($number_results); }

La clase Paginator.php:
/* *customsiteframeworkmaybefreelydistributedundertheextended3clause BSDlicense *Foralldetailsanddocumentation: *https://sourceforge.net/projects/customsite/ * *CreatedbyCarlosRodriguezdelMoralon2012. * *Copyright(c)2012CarlosRodriguezdelMoral *Allrightsreserved. */ classPaginatorimplementsiPaginator{ constNUMBERED=1; constSIMPLE=2; constAZ=3; private$_paginator; private$_frmt; publicfunction__construct($paginator_type=Paginator::SIMPLE, $options='',$frmt=''){ $this>_frmt=$frmt; switch($paginator_type){ casePaginator::NUMBERED: /* OptionsforPaginatorNumbered Limitindicator:10=1to10. Start(Inicio)Link(Start0,1,2...) Next(Siguiente)Link(Start0,1,2...Next>) */ if($options=='') $options=array('limit'=>10,'start'=>false,'next' =>true); $this>_paginator=newPaginatorNumbered($options,$this >_frmt); break; casePaginator::SIMPLE: /* OptionsforPaginatorSimple */ if($options=='') $options=array('options'=>false); $this>_paginator=newPaginatorSimple($options,$frmt); break; casePaginator::AZ: /* *OptionsforPaginatorAZ *uppercase=true(uppercase):false(lowercase)

*/ if($options=='') $options=array('uppercase'=>true); $this>_paginator=newPaginatorAZ($options,$frmt); break; } } publicfunctionflush(){ $this>_paginator>flush(); } publicfunctionsetresultsnumber($number_results){ $this>_paginator>setresultsnumber($number_results); } //Thesemethodsarereadyforadynamicversionwithservicesandobject statenotimplementedyet publicfunctiongotopage($offset){ $this>_paginator>gotopage($offset); } publicfunctionnext(){ $this>_paginator>next(); } publicfunctionprev(){ $this>_paginator>prev(); } publicfunctionupdate(){ $this>_paginator>update(); } } ?>

La Clase PaginatorSimple:
/* *customsiteframeworkmaybefreelydistributedundertheextended3clause BSDlicense *Foralldetailsanddocumentation: *https://sourceforge.net/projects/customsite/ * *CreatedbyCarlosRodriguezdelMoralon2012. * *Copyright(c)2012CarlosRodriguezdelMoral *Allrightsreserved. */ classPaginatorSimpleextendsHtmlFormatOutput implementsiPaginator { protected$_page; protected$_paginator_buffer;

protected$_results_number; protected$_options; publicfunction__construct($options,$frmt){ global$page; $this>_page=$page; $this>_options=$options; if(isset($frmt)&&is_array($frmt)){ $this>format($frmt); } } publicfunctionformat(array$frmt){ $this>set_format_start($frmt['start']); $this>set_format_end($frmt['end']); $this>buffer.=$this>frmt_start; } publicfunctionflush(){ $this>buffer.=$this>_paginator_buffer; parent::flush(); } publicfunctiongetBuffer(){ $this>buffer.=$this>_paginator_buffer; returnparent::getBuffer(); } publicfunctionsetresultsnumber($number_results){ $this>_results_number=$number_results; $this>build($this>_options); } protectedfunctionbuild($options){ /* OptionsforPaginatorSimple */ $this>_paginator_buffer='<ulclass="pager">'; if($this>_page>1){ $this>_paginator_buffer.= '<liclass="previous"><ahref=".'.URL::geturi().';'.($this >_page1).'">Previous</a></li>'; }else{ $this>_paginator_buffer.= '<liclass="previousdisabled"><ahref="#">Previous</a></li>'; } if($this>_results_number>$this>_page){ $this>_paginator_buffer.= '<liclass="next"><ahref=".'.URL::geturi().';'.($this >_page+1).'">Next</a></li>'; }else{ $this>_paginator_buffer.= '<liclass="nextdisabled"><ahref="#">Next</a></li>'; } $this>_paginator_buffer.='</ul>'; }

//Thesemethodsarereadyforadynamicversionwithservicesandobject statenotimplementedyet publicfunctiongotopage($offset){ } publicfunctionnext(){ } publicfunctionprev(){ } publicfunctionupdate(){ }

} ?>

La clase PaginatorNumber:
<?php /* *customsiteframeworkmaybefreelydistributedundertheextended3clause BSDlicense *Foralldetailsanddocumentation: *https://sourceforge.net/projects/customsite/ * *CreatedbyCarlosRodriguezdelMoralon2012. * *Copyright(c)2012CarlosRodriguezdelMoral *Allrightsreserved. */ /** *DescriptionofPaginatorNumbered * *@authorcharlyasap */ classPaginatorNumberedextendsPaginatorSimple{ publicfunction__construct($options,$frmt){ parent::__construct($options,$frmt); } //Override protectedfunctionbuild($options){ /* OptionsforPaginatorNumbered Limitindicator:10=1to10. Start(Inicio)Link(Start0,1,2...) Next(Siguiente)Link(Start0,1,2...Next>) */ $this>_paginator_buffer='<divclass="pagination"><ul>'; if(isset($options['start'])&&$options['start']==TRUE){

$this>_paginator_buffer.= '<liclass="enabled"><a href=".'.URL::geturi().';0">Start</a></li>'; }else{ $this>_paginator_buffer.= '<liclass="disabled"><ahref="#">Start</a></li>'; } $start_offset=1; $limit=10;//defaultlimit if(isset($options['limit'])&&$options['limit']){ $limit=$options['limit']; } $start_offset=floor(($this>_page/$limit))*$limit; if($start_offset==0)$start_offset=1; for($i=$start_offset;$i<$start_offset+$limit;++$i){ if($this>_results_number==$i)break; if($i==$this>_page){ $this>_paginator_buffer.='<liclass="active"><a href=".'.URL::geturi().';'.$i.'">'.$i.'</a></li>'; }else{ $this>_paginator_buffer.='<li><ahref=".'.URL::geturi().';'. $i.'">'.$i.'</a></li>'; } } if(($start_offset+$limit)<$this>_results_number){ if(isset($options['next'])&&$options['next']==TRUE){ $this>_paginator_buffer.='<liclass="enabled"><a href=".'.URL::geturi().';'.($this>_page+1).'">Next</a></li>'; }else{ $this>_paginator_buffer.='<liclass="disabled"><a href="#">Next</a></li>'; } } $this>_paginator_buffer.='</ul></div>'; } } ?>

La Clase PaginatorAZ:
/* *customsiteframeworkmaybefreelydistributedundertheextended3clause BSDlicense *Foralldetailsanddocumentation: *https://sourceforge.net/projects/customsite/ *

*CreatedbyCarlosRodriguezdelMoralon2012. * *Copyright(c)2012CarlosRodriguezdelMoral *Allrightsreserved. */ classPaginatorAZextendsPaginatorSimple{ publicfunction__construct($options,$frmt){ parent::__construct($options,$frmt); $this>build($this>_options); } //Override protectedfunctionbuild($options){ /* *OptionsforPaginatorAZ *uppercase=true(uppercase):false(lowercase) */ $this>_paginator_buffer='<divclass="pagination"><ul>'; if(!is_numeric($this>_page)&&strlen($this>_page)==1){ if(isset($options['uppercase'])&&$options['uppercase']==TRUE) { $current_char=ucfirst($this>_page); $start_char='A'; $end_char='Z'; }else{ $current_char=strtolower($this>_page); $start_char='a'; $end_char='z'; } }else{ $current_char='A'; $start_char='A'; $end_char='z'; } foreach(range($start_char,$end_char)as$i){ if($i==$current_char){ $this>_paginator_buffer.='<liclass="active"><a href=".'.URL::geturi().';'.$i.'">'.$i.'</a></li>'; }else{ $this>_paginator_buffer.='<li><ahref=".'.URL::geturi().';'. $i.'">'.$i.'</a></li>'; } } $this>_paginator_buffer.='</ul></div>'; } //InthisversionofAZwedon'thavetosetresultsnumberbeforebuild. publicfunctionsetresultsnumber($number_results){ $this>_results_number=$number_results; } } ?>

Para testear un componente por separado siempre es bueno hacerlo desde un fichero temporal en raiz, en nuestro caso este fichero ser test_paginator.php:
<linkrel="stylesheet"href="/css/bootstrap.min.css"/> <scripttype="text/javascript"src="/js/libs/jquery/jquerymin.js"></script> <scripttype="text/javascript" src="/js/libs/bootstrap/bootstrap.min.js"></script> <?php //3denoviembre2012. //@authorcharlyasap //CARLOSRODRIGUEZDELMORAL global$page; include"components/paginator/iPaginator.php"; include"lib/HtmlFormatOutput.php"; include"lib/URL.php"; include"components/paginator/PaginatorSimple.php"; include"components/paginator/PaginatorNumbered.php"; include"components/paginator/PaginatorAZ.php"; include"components/paginator/Paginator.php"; $page=URL::getpage(); $options=array('uppercase'=>TRUE); $frmt=array('start'=>'<divstyle="margin:5em;marginleft:auto;margin right:auto">','end'=>'</div>'); $paginator=newPaginator(Paginator::AZ,$options,$frmt); //$paginator>setresultsnumber(15);//AmustintheotherPaginatorsnotin PaginatorAZ $paginator>flush();//view'scomponentsmanagerwillcallthismethod ?>

Ahora abrimos nuestro navegador y escribimos la siguiente url: http://localhost/test_paginator.php;A Obtendremos un paginador A-Z Una ltima cosa a tener en cuenta, para este componente hemos utilizado la librera CSS boostrap, la cual podreis descargar desde la siguiente url: http://twitter.github.com/bootstrap/components.html#pagination Fin del tutorial, espero que os haya servido de ayuda.