jueves, 6 de diciembre de 2012

Menú Dinámico Bootstrap Twitter

Avanzando con el proyecto dejo a consideración una posible solución para integrar un menú dinámico utilizando la librería de Bootstrap Twitter, primero definimos la estructura de la tabla que contendrá la información del menú.


El campo men_id es el identificador de la tabla que contiene la información del menu como titulo, contenido, fecha de creación,etc. el campo nivel es el grado de profundidad de la opción en la estructura de etiquetas html. nivel 0 es el enlace de primer orden.

Creamos el modelo que interactúa con la tabla menudinamicos.

1   <?php
2  
3  
class Application_Model_DbTable_Menudinamico extends Zend_Db_Table_Abstract
4  
{
5  
6     protected 
$_name 'menudinamicos';
7     protected 
$_primary 'id';
8     protected 
$_menu = array();
9     protected 
$_path;
10  
11     public function 
baseUrl()
12     {
13         
14       
$ruta $front Zend_Controller_Front::getInstance();
15       
$this->_path $ruta->getBaseUrl();
16     }
17     
18     public function 
menuPrincipal()
19     {
20      
21         
$this->_menu[] = '<div class="navbar navbar-fixed-top">
22                  <div class="navbar-inner">
23                  <div class="container-fluid">
24                  <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
25                      <span class="icon-bar"></span>
26                      <span class="icon-bar"></span>
27                      <span class="icon-bar"></span>
28                  </a>
29                  <a class="brandImg" href="#"><img src="/img/logo.png"></a>
30                  <div class="btn-group pull-right">
31                      <a class="btn dropdown-toggle" data-toggle="dropdown" href="#">
32                      <i class="icon-user"></i> Atención al Ciudadano
33                      <span class="caret"></span>
34                      </a>
35                      <ul class="dropdown-menu">
36                      <li><a href="/index/">Quejas y Reclamos</a></li>
37                      <li class="divider"></li>
38                      <li><a href="/index/id/8">Preguntas Frecuentes</a></li>
39                      <li><a href="/index/id/2">Glosario</a></li>
40                      <li><a href="http://www.colombiaparticipa.com/armenia/?pagina=contratos.php">Contratación COVI</a></li>
41                      <li><a href="/index/id/5">Registrarse</a></li>
42                      </ul>
43                  </div>'
;
44         
45         
$this->_menu[] = '<div class="nav-collapse">
46                      <ul class="nav">
47                      <li class="active"><a href="/index"><i class="icon-home"> </i> Inicio</a></li>
48                      <li><a href="index/menu/id/mapa"><i class="icon-list-alt"></i> Mapa del Sitio</a></li>
49                      <li><a href="index/menu/id/correo"><i class="icon-envelope"></i> Correo Institucional</a></li>
50                      <li><a href="index/menu/id/glosario"><i class="icon-question-sign"></i> Glosario</a></li>
51                      <li class="dropdown">
52                          <a data-toggle="dropdown" class="dropdown-toggle" href="#">
53                          <i class="icon-info-sign"></i> Menú Principal<b class="caret"></b></a>'
;
54                          
55      
$this->_menu[] = '<ul class="dropdown-menu">';
56      
$query $this->select();
57        
$query->where('eliminar = ?''0');
58        
$query->where('nivel = ?','0');
59        
$results $this->fetchAll($query);
60        foreach(
$results AS $result) {
61             
62          
$sql "SELECT COUNT(*) FROM menudinamicos where eliminar = 0 and nivel =1 and parent =".$result->id;
63          
$resul $this->fetchAll($sql);
64          
$rowCount count($resul);
65          if(
$rowCount == 0){
66              
67              
$this->_menu[] = ' <li><a href="'.$this->_path.'/index/menu/id/'.$result->men_id.'">'.$result->nombre.'</a></li>';
68          
// opciones de nivel 0 sin Submenu
69          
}else{
70              
71             
// opciones de nivel 0 CON SUBMENU 
72            // aqui entran ROW[]-> ID = 1-3-8-9
73              
$this->_menu[] = ' <li class="dropdown submenu"><a href="#" class="dropdown-toggle" data-toggle="dropdown">'.$result->nombre.'</a>'
74              
$query $this->select();
75              
$query->where('eliminar = ?''0');
76              
$query->where('nivel = ?','1');
77              
$query->where('parent = ?',$result->id);
78             
79              
$resul $this->fetchAll($query);
80              
$this->_menu[] ='<ul class="dropdown-menu submenu-show submenu-hide">';
81              foreach(
$resul AS $subnivelOne) {
82                 
$sql "SELECT COUNT(*) FROM menudinamicos where eliminar = 0 and nivel =2 and parent =".$subnivelOne->id;
83                 
$resultOne $this->fetchAll($sql);
84                 
$rowCountOne count($resultOne);
85              if(
$rowCountOne==0){
86                  
// Opciones de Nivel 1 sin SubMenu Nivel 2  
87                 
$this->_menu[]='<li><a href="'.$this->_path.'/index/menu/id/'.$subnivelOne->men_id.'">'.$subnivelOne->nombre.'</a></li>';  
88                     
89                 }else{
90                     
91                   
$this->_menu[] ='<li class="dropdown submenu"><a href="#" class="dropdown-toggle" data-toggle="dropdown">'.$subnivelOne->nombre.'</a>';
92                   
$this->_menu[] ='<ul class="dropdown-menu submenu-show submenu-hide">';
93                   
$query $this->select();
94                   
$query->where('eliminar = ?''0');
95                   
$query->where('nivel = ?','2');
96                   
$query->where('parent = ?',$subnivelOne->id);
97                   
$resul $this->fetchAll($query);
98                             
99                   foreach(
$resul AS $subnivelTwo) {    
100                    
101                      
$sql "SELECT COUNT(*) FROM menudinamicos where eliminar = 0 and nivel =3 and parent =".$subnivelTwo->id;
102                      
$resultTwo $this->fetchAll($sql);
103                      
$rowCountTwo count($resultTwo);
104                      if(
$rowCountTwo==0){
105                           
$this->_menu[] ='<li><a href="'.$this->_path.'/index/menu/id/'.$subnivelTwo->men_id.'">'.$subnivelTwo->nombre.'</a></li>'
106                      }else{
107                          
$this->_menu[] ='<li class="dropdown submenu"><a href="#" class="dropdown-toggle" data-toggle="dropdown">'.$subnivelTwo->nombre.'</a>';
108                          
$this->_menu[] ='<ul class="dropdown-menu submenu-show submenu-hide">'
109                          
$query $this->select();
110                          
$query->where('eliminar = ?''0');
111                          
$query->where('nivel = ?','3');
112                          
$query->where('parent = ?',$subnivelTwo->id);
113                          
$resul $this->fetchAll($query);
114                          foreach(
$resul AS $subnivelThree) {
115                              
116                             
$this->_menu[] ='<li><a href="'.$this->_path.'/index/menu/id/'.$subnivelThree->men_id.'">'.$subnivelThree->nombre.'</a></li>';    
117  
118                          }
119  
120                          
$this->_menu[] ='</ul>';
121                          
$this->_menu[] = '</li>'
122                      }
123                       
124                       
125                   }
// final foreach subnivelTwo 
126                   
$this->_menu[] ='</ul>';
127                   
$this->_menu[] = '</li>';   
128                 } 
129                  
130                  
131              
132              }
// fin foreach interno subnivel 1
133              
134              
$this->_menu[]='</ul>';
135              
$this->_menu[]= '</li>';
136              
137          }
//fin del else
138           
139          
140        
}// foreach principal
141        
142       
$this->_menu[] = '</ul><!--/class="dropdown-menu -->';
143       
$this->_menu[] = '</li><!--/class="dropdown -->';
144       
$this->_menu[] = '</ul><!--/class NAV -->';
145       
$this->_menu[] = '<form class="navbar-search pull-left">'
146               
.'<input type="text" class="search-query" placeholder="Buscar..."></form>'
147               
.'</div></div></div></div><!--/.nav-collapse -->';  
148          
149       return 
$this->_menu;   
150          
151   } 
152      
153      
154      
155  }



En el Bootstrap


protected function _initDatabase()
    {

       date_default_timezone_set('America/Bogota');
       $dbResource = $this->getPluginResource('db');
       $this->_db = $dbResource->getDbAdapter();
       Zend_Registry::set('db', $this->_db);

    }



protected function _initMenuPrincipal()
    {
       
        $this->bootstrap('layout');
        $layout = $this->getResource('layout');
        $view = $layout->getView();
        $dbAdapter = Zend_Registry::get("db");   
        $menu = new Application_Model_DbTable_Menudinamico($dbAdapter);
        $navigation = $menu->menuPrincipal();
        $view->menuBootrap = $navigation;
       
        
    }



En el Layout:


 foreach ($this->menuBootrap as $item) {
         echo $item;   
       }



Listo !! quedo atento a sus comentarios



domingo, 1 de julio de 2012

Pruebas Online Zend Framework

Una de las formas para superar la prueba de certificación es practicando de forma constante, he encontrado algunos sitios que facilitan online una serie de preguntas para medir nuestro conocimiento de ZF. algunos de estos sitios realizan además prueba de conocimientos básicos de PHP

http://www.coursehero.com/flashcards/study/?fcsid=434026

http://quiz.thefullwiki.org/Zend_Framework

http://www.bestwebframeworks.com/quizzes/php/2/zend-framework/
http://www.phpriot.com/quiz/index/index
http://www.coursehero.com/flashcards/study/?fcsid=301949

lunes, 25 de junio de 2012

CSS Diferentes en LAYOUT - MODULAR

Cuando se cuenta con una estructura modular todos los Bootstrap de la aplicación  son ejecutados en el proceso de inicialización, así  el módulo no sea solicitado. De esta forma no se podría hacer independencia para vincular de forma exclusiva CSS o JS o el nombre de cada módulo. la solución a este inconveniente lo puede realizar un Plugin.



class Plugins_Layouts extends Zend_Controller_Plugin_Abstract

 private $_nombreModulo;
 public function preDispatch(Zend_Controller_Request_Abstract $request) 
 { 
    //Obtener view de esta forma porque se encuentra definida en
    //resources.view[] dentro de application.ini 
    $view = Zend_Controller_Front::getInstance()        ->getParam('bootstrap')        ->getResource('view');
    $this->_nombreModulo = $request->getModuleName(); 
    $layout = Zend_Layout::getMvcInstance();
    switch ($this->_nombreModulo)
 { 
   case 'admin':                $layout->setLayout('admin'); 
   $view->headLink()->appendStylesheet($view->baseUrl("css/menuAdmin.css"));
   $view->headLink()->appendStylesheet($view->baseUrl("css/templateAdmin.css"));
   $view->headScript()->appendFile($view->baseUrl("js/menuAdmin.js"));
   $view->headTitle('Zona de Administración','APPEND');
   break; 
   case 'biblioteca':                $layout->setLayout('biblioteca');
   break; 
   default:                $layout->setLayout('default');
               $view->headLink()->appendStylesheet($view->baseUrl("css/menuDefault.css"));
               $view->headLink()->appendStylesheet($view->baseUrl("css/templateDefault.css"));  
               $view->headScript()->appendFile($view->baseUrl("js/menuDefault.js")); 
               $view->headTitle('Default','APPEND');
               break;
 } } }

martes, 19 de junio de 2012

Layout para cada Módulo

En nuestra estructura  modular se han diseñado 3 módulos, default, admin y bibloteca, para facilitar el cambio del layout se ha creado un Front Controller Plugin.

Que es un Front Controller Plugin
Es un clase que extiende de Zend_Controller_Plugin_Abstract que permite mejorar el comportamiento y la versatilidad de nuestra aplicación, ahorrando muchas lineas de código a través de los controllers. El Front Controller Plugin permite interceptar a través de seis eventos o hooks y ejecutar ciertas acciones que nos facilitaran el trabajo.

  • routeStartup () : antes de la solicitud de enrutamiento
  • routeShutdown () : después de la solicitud de enrutamiento
  • dispatchLoopStartup () : antes de entrar en el bucle de envío
  • preDispatch () : antes de despachar una acción individual
  • postDispatch () : tras el envío de una acción individual
  • dispatchLoopShutdown () : después de completar el bucle de envío

Registro de plugins application.ini
;Registrar Plugins
autoloaderNamespaces[] = "Plugins_"
resources.frontController.plugins.Layouts = "Plugins_Layouts"

Indica que en el directorio de library se creará una carpeta Plugins y que la clase se llamará Layouts.php. Con la linea resource.frontController.plugins, registramos y activamos el plugin, aunque tambien lo podemos hacer en el Bootstrap

Crear la clase Layouts

class Plugins_Layouts extends Zend_Controller_Plugin_Abstract {

private $_nombreModulo;

public function preDispatch(Zend_Controller_Request_Abstract $request)
{
$this->_nombreModulo = $request->getModuleName();
$layout = Zend_Layout::getMvcInstance();

switch ($this->_nombreModulo)
{
case 'admin':
$layout->setLayout('admin');
break;

case 'biblioteca':
$layout->setLayout('biblioteca');
break;

default:
$layout->setLayout('default');
break;
}
}
}


La clase será utilizada en el evento preDispatch

Activar de plugin en Bootstrap

protected function _initRegisterPlugins()

    {
      $front = Zend_Controller_Front::getInstance();
      $front->registerPlugin(new Plugins_Layouts());  
        
    }

Con esta funcionalidad al cambiar de modulo, automáticamente se cambiará el layout de la aplicación. Adicional a éste podríamos organizarlo para detectar el perfil del usuario y mostrar un layout especifico.


lunes, 18 de junio de 2012

School2.0 - Software de Notas

Ante el incremento de aplicaciones en la nube, el área educativa es una de las más favorecidas, abarcando un sinnúmero de componentes que pretenden mejorar el aprendizaje de los alumnos o mejorar los servicios administrativos en las entidades educativas. Desde este blog pretendo involucrar el proyecto "School2.0" que será de gran utilidad para la administración de calificaciones de los alumnos de instituciones educativas.

El proyecto será desarrollando en Zend Framework 1.11 y en la medida que se avance, podrá ser visualizado en linea, espero sus comentarios o aportes a esta cruzada.

School2.0


Dentro de la estructura de School2.0 se establece una zona publica que podría ser el Website de la institución educativa y la zona administrativa donde según el rol asignado al usuario podría realizar ciertas tareas permitidas.

Comenzaré con la zona administrativa y para ello tendré un login que permitirá detectar que tipo de usuario ha ingresado al sistema. Nuestra estructura del proyecto debe ser modular, en el anterior post se aclaro el tema


El Sitio de prueba en linea estará en el subdominio http://school2.0.armeniadigital.com, espero sea de gran interés.

Zend Framework Modular - Netbeans


A través de los diferentes post se ha trabajado sin estructura modular, todos los controladores se encuentran dentro de la carpeta CONTROLLERS,  dentro de las ventajas de utilizar una aplicación modular  se encuentran: ejecutar ciertas acciones por modulo mediante su propio Bootstrap, reutilizar modelos, mejor entendimiento de aplicaciones grandes y/o complejas y aplicaciones flexibles y escalables.

Utilizando Netbeans seria de la siguiente forma


1. Click derecho sobre el proyecto y buscamos zend  para utilizar comandos.



2. Digitamos en Filter module y aparecerá la sintaxis del comando para crear el modulo, en parametros escribimos el nombre del módulo


3. de forma automatica Zend Tools creará el modulo y adicionará lineas de configuración en application.ini


4. Al crear el módulo la carpeta controllers esta vacia, crearemos el controller index y la vista del indexAction

5. adicionamos lineas de configuración en application.ini, para determinar el módulo por defecto.

En application.ini
[production]
….
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
resources.frontController.params.prefixDefaultModule = "1"
resources.frontController.defaultModule = "default"
resources.modules[] = ""



6. estructura modular, reorganizando los controllers que estaban por fuera de los modulos, se puede dejar models por fuera para reutilizar código. 
Se crean los Bootstrap de los módulos.

El Bootstrap del modulo  default será:

class Default_Bootstrap extends Zend_Application_Module_Bootstrap{
    
     
}



7. En el nombre de los controllers, a excepción del módulo default todos deben tener como primer nombre, el del módulo.

Con estos pasos nuestra estructura modular estará funcionando sin inconvenientes, mucha suerte


viernes, 15 de junio de 2012

Layout II - Twitter Bootstrap

Cuando activamos el layout como maqueta para organizar, dar una mejor presentación a nuestra aplicación y reutilizar estructuras html (zf enable layout) , se adicionará en application.ini las líneas de configuración por defecto


resources.layout.layout = “layout”
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts/"


La primera nos indica el nombre por defecto del archivo  .phtml en este caso es “layout.phtml” y la segunda el path de ubicación del layout. Inicialmente el archivo “layout” creado contiene lo siguiente:


<?php  echo $this->layout()->content; ?>


content  hace referencia al contenido del  VIEW  que corresponde al ACTION del CONTROLLER  que estamos ejecutando, nuestro layout puede ser “armado” con otros archivos .phtml , miremos  la gráfica para tener una idea de las posibles opciones a vincular.




Accediendo al objeto Layout
Cuando se registra en application.ini las líneas de configuración del layout (resources) esto nos permitirá tener acceso a una instancia de Zend_Layout, bien sea con los Action o los View Helper, la siguiente tabla muestra las diferentes formas de obtener la instancia de la clase.
En las Vistas o layout En los Action En el Bootstrap
<?php $layout = $this->layout()?> $layout = $this->_helper->layout();
$this->bootstrap('layout');
       $layout = $this->getResource('layout');


Metodos
Despues de recuperar la instancia de Zend_Layout podemos utilizar los siguientes métodos

Desactivar el layout por defecto
  • $this->_helper->layout()->disableLayout();
Activar el layout
  • $this->_helper->layout()->enableLayout()
Cambiar el layout por defecto


//desde el controlador
  • $this->_helper->layout()->setLayout('main');
//desde la vista
  • <?php $this->layout()->setLayout('footer'); ?>
Asignar variables


//en el  Action
  • $this->_helper->layout()->assign('footer', 'footer.phtml');
O
  • $this->_helper->layout()->usuario = 'carlos Fernando';
En el layout
  • echo $this->layout()->usuario;

Diseñar el Layout


Cuando nos enfrentamos al diseño de nuestro layout comienza el tiempo a hacer de las suyas, fácilmente perdemos tiempo valioso que puede ser “invertido” en temas propios del desarrollo. Aquí aparecen algunos aliados importantes, al igual que nuestro Zend Framework  en PHP, en el diseño de  CSS aparecen varios framework  como un kit de poderosas herramientas para desarrollo rápido de aplicaciones y sitios web, aportando la magnífica idea de recopilar un sinnúmero de clases que nos permitirán en corto tiempo tener una estructura organizada, limpia y de fácil configuración, en mi caso particular me llamo mucho la atención Twitter Bootstrap( less css http://lesscss.org), desarrollado  por  ingenieros de Ttwitter , utilizando  la semántica de  HTML 5 y bajo la modalidad de open source. La versión actual es la 2.0.3 que trabaja sobre diseños fijos, fluidos o basados sobre porcentajes y sensibles (responsive) a dispositivos móviles


Descarga de libreria
https://github.com/twitter/bootstrap.


Inicializar CSS en nuestro Bootstrap


protected function _initTwitterBootstrap()
   {
       $this->bootstrap('View');
       $view = $this->getResource('View');
       $view->headMeta()->appendName('viewport', "width=device-width, initial-scale=1.0");
       $view->headLink()->appendStylesheet($view->baseUrl("css/bootstrap.css"));
       $view->headLink()->appendStylesheet($view->baseUrl("css/bootstrap-responsive.css"));
}


bootstrap.css librería básica
bootstrap-responsive.css nos permite generar sitios sensibles a las dimensiones de los dispositivos que navegan nuestra aplicación.


Como usarla
Para que Twitter Bootstrap funcione adecuadamente nuestra estructura del layout HTML debe ser igual a :
  1. <!DOCTYPE html>
  2. <html lang="es">
  3.   ...
  4. </html>
Plantilla básica Fija
Por defecto la plantilla básica de Twitter Bootstrap tiene 940 pixel de ancho (.container) en 12 columnas, además contiene 4  variantes para dispositivos móviles que veremos más adelante, como primera medida y facilidad de aprendizaje debemos tener  en cuenta la siguiente tabla y así darle organización a nuestro layout


.span12 .span11 .span10 .span9 .span8 .span7 .span6 .span5 .span4 .span3 .span2 .span1
940px 860px 780px 700px 620px 540px 460px 380px 300px 220px 140px 60px


Además para Twitter Bootstrap la clase .row  crea FILAS  y la clase .span  crea COLUMNAS.  Vamos a la practica!
Comenzare por el layout más simple una sola FILA y una sola  COLUMNA


<!doctype html>
<html lang="es">
<head>
<meta charset="utf-8" />
<title>Layout ZendFramework</title>
<link href="css/bootstrap.css" rel="stylesheet">
<!--[if IE]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<div class="container">
<div class="row">
<div class="span12">
….
</div>
<div>
</div>
</body>
</html>


El siguiente ejemplo tiene una FILA y 2 COLUMNAS y así podríamos hacer varias modificaciones, lo más importante a tener en cuenta es que la suma de los números utilizados en  el elemento SPAN (.spanX) no supere las 12 columnas que tiene por defecto la plantilla fija.
las siguientes combinaciones de .span válidas


.span6    y  .span6  (6+6)     = 2 Columnas a 460 Pixel
.span4    y  .span 8    (4+8)  = 2 Clumnas  300 y 620 Pixel
.span10 y  .span2   (10+2)  = 2 Columnas 780 y 140 Pixel


<div class="container">
<div class="row">
<div class="span6">
<h1>una FILA, DOS COLUMNA </h1>
</div>
<div class="span6">
<h1>una FILA, DOS COLUMNA </h1>
</div>
</div>
</div>
Tambien podrías hacer
<div class="row">
<div class="span12">
Una FILA que contiene otra FILA dividida en DOS Columnas
<div class="row">
<div class="span6">COLUMNA 1</div>
<div class="span6">COLUMNA 2</div>
</div>
</div>
</div>


El solo hecho de tener    <div class="container"> esta clase nos indica que nuestra aplicación será visualizada a 940Pixel y si el dispositivo donde se visualiza no tiene esta resolución aparecerá la barra horizontal inferior para hacer el scroll, algo que no es bien visto de nivel profesional.

Plantilla básica flexible
Para evitar los inconvenientes de las plantillas fijas podemos trabajar con base en los porcentajes según lo permita el dispositivo de visualización, para eso simplemente cambiamos

<div class="container">
<div class="row">
Por
<div class="container-fluid">
<div class="row-fluid">


Plantilla básica Sensitiva
Con esta alternativa nuestro layout  será visualizado en diferentes dispositivos y resoluciones de pantallas de una forma adecuada, facilitando la navegabilidad por la aplicación o sitio Web. Como primera medida  se debe incluir


<meta name="viewport" content="width=device-width, initial-scale=1.0">


Además de:
<link href="css/bootstrap/bootstrap.min.css" rel="stylesheet">
<link href="css/bootstrap/bootstrap-responsive.min.css" rel="stylesheet">


Herramientas
El incremento de uso del framework ha permitido la aparición de herramientas que nos permiten configurar la apariencia de fondos, botones, colores,etc




http://charliepark.org/bootstrap_buttons/
http://www.eyecon.ro/colorpicker-and-datepicker-for-twitter-bootstrap.htm
http://stylebootstrap.info/
http://blueimp.github.com/Bootstrap-Image-Gallery/