Despabilando la MonoNeurona::Internet es de todos [Inicio] [Regresar]
WWW \ CakePHP: Bloques en el layout
WWW
CakePHP: Bloques en el layout

Este artículo ha sido consultado en 1,266 ocasiones.

Nivel en CakePHP: inicial. 

Este tutorial ilustra como resolver una cuestión que todos los novatos encontramos en CakePHP: como poblar el layout (template) de la página con información de diferentes tablas en diferentes lugares del layout.  

Bien, supongamos que tenemos la tabla entries en postgresql, sqlite, firebird o mysql:

-- entries in the users blogs
CREATE TABLE entries (
id serial PRIMARY KEY,   - duh!
title varchar(50) NOT NULL,
body text NOT NULL,
category_id int REFERENCES categories (id) ON DELETE CASCADE,   -- the table categories must exist pal!!
created timestamp(0) with time zone DEFAULT now() NOT NULL,
state int NOT NULL DEFAULT 0,  -- is the entry published (1) or still draft (0)
user_id int REFERENCES users (id) ON DELETE CASCADE,
disc int NOT NULL DEFAULT 0   -- discution in the entry,   Activ/Desactiv   1/0
);

Para manejar esta tabla en CakePHP necesito el modelo Entry:

<?php
//AppModel gives you all of Cake's Model functionality

class Entry extends AppModel
{
    // Its always good practice to include this variable.
    public $name      = 'Entry';
    public $belongsTo = 'User, Category';   // las entradas pertenecen al usuario y a la categoria o tema

      // esto debe coincidir con los NOT NULL de la tabla
      public $validate = array(
      'title' => VALID_NOT_EMPTY,         //'/[a-z0-9\\\\\\\\\\\\\\\\_\\\\\\\\\\\\\\\\-]{3,}$/i',
      'user_id' => VALID_NOT_EMPTY,
      'body' => VALID_NOT_EMPTY,
      'state' => VALID_NOT_EMPTY
   );
}

?>

el controlador EntriesController:
Archivo: app/controllers/entries_controller.php

<?php
class EntriesController extends AppController
{
    public $helpers    = array('Html', 'Javascript', 'Ajax', 'Form');
        
    public function listing() {
      
       $this->layout    = 'blog';
      
       $data = $this->Entry->findAll();
      
       $this->set('data', $data);
       }
}
?>

y la vista:
Archivo:app/views/entries/listing.thtml

<?php
//die(print_r($data));  // esto es util para conocer como viene $data

foreach ($data as $key => $val) {
      echo $data[$key]['Entry']['title'] . "<br />";
      echo $data[$key]['Entry']['body'] . "<br />";
      echo $data[$key]['Entry']['created'] . "<br />";
}
?>

Como vemos en el controlador, estamos usando el layout blog.thtml:
Archivo: app/view/layout/blog.thtml

<html>
<body> 

<table>
<tr>
    <td colspan="2">El header</td></tr>

   <tr><td style="width:30%;vertical-align:top;padding:10px;" id="left">
   <p>Esto es estático</p> 

    </td> 

   <td style="width:70%;vertical-align:top;padding:10px;" id="main">
     <?php echo $content_for_layout ?>
</td>
</tr> 

   <tr><td colspan="2">El Footer</td></tr>
</table>
</body>
</html>

Este layout no debe ser tomado muy en serio, tan sólo deseo usarlo para ilustrar el problema, todo nuestro proceso MVC de la tabla entries será colocado en <?php echo $content_for_layout ?>, es decir en la columna "main" de la tabla.

¿Pero qué pasa si deseo más contenido en otras zonas del layout? Por ejemplo si tengo, una tabla "sections":

CREATE TABLE sections {
id serial PRIMARY KEY,
name varchar(20) NOT NULL,
order int NOT NULL
}

y deseo colocar su contenido en la columna "left" del layout, ¿cómo puedo hacerlo? Fácil!! el secreto está en usar elements, que son pequeñas extensiones de las vistas.

La tabla sections no tiene nada que ver con entries de modo que para utilizar sections desde del controlador EntriesController debemos usar:

loadModel('Section'); 

para cargar el modelo de sections. De  modo que el controlador queda así:

<?
loadModel('Section');
class EntriesController extends AppController
{
    public $helpers    = array('Html', 'Javascript', 'Ajax', 'Form');
        
    public function listing() {
      
       $this->layout    = 'blog';
      
       $data = $this->Entry->findAll();
      
       $this->set('data', $data);

       $this->Section = new Section;    // inicializo el modelo "externo"
       $this->set('sections', $this->Section->findAll());

       }
}
?> 

Ahora creamos nuestro element:

Archivo: app/view/elements/sections.thtml

<div class="titles">Sections</div>
<?
//var_dump($sections);  //esto es para ver el array $sections

$p = count($sections);

foreach ($sections as $key => $val) {
  echo '<a class="petit" href="/sections/show/'. $sections[$key]['Section']['id'] . '">&gt;'. $sections[$key]['Section']['name'] . '</a><br />';
}

if ($p > 10 )
{
    echo '<p><a class="petit" href="/sections/all/">View all sections</a></p>';
}
?>

Y llamamos al element desde el layout:

<html>
<body> 

<table>
<tr>
    <td colspan="2">El header</td></tr>

   <tr><td style="width:30%;vertical-align:top;padding:10px;" id="left"> 
  <p>Esto es estático</p> 

<?php
if ( $sections != null )
{
     echo $this->renderElement('sections', $sections);
}

?>
</td> 

   <td style="width:70%;vertical-align:top;padding:10px;" id="main">
     <?php echo $content_for_layout ?>
</td>
</tr> 

   <tr><td colspan="2">El Footer</td></tr>
</table>
</body>
</html>

Y eso es todo!! Obviamente podemos crear todos los elements que necesitemos para colocarlos en nuestro template. CakePHP rulezzzz!!!
 


Última actualización: 2007-04-29 10:56:59-05



ir arriba
The Queen is here Mozilla Firefox The Best DataBase CakePHP Framework CSS GNU Hacker