PageRenderTime 56ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/es/tutorials-and-examples/blog/part-two.rst

https://gitlab.com/albertkeba/docs
ReStructuredText | 643 lines | 499 code | 144 blank | 0 comment | 0 complexity | aa66df57670d02eed7b85ab746e3aeef MD5 | raw file
  1. Parte 2: Tutorial para desarrollar el Blog
  2. ##########################################
  3. Creando un modelo para los artículos (*Post Model*)
  4. ===================================================
  5. Los modelos son una parte fundamental en CakePHP. Cuando creamos un modelo,
  6. podemos interactuar con la base de datos para crear, editar, ver y borrar con
  7. facilidad cada ítem de ese modelo.
  8. Los ficheros en los que se definen los modelos se ubican en la carpeta
  9. ``/app/Model``, y el fichero que vamos a crear debe guardarse en la ruta
  10. ``/app/Model/Post.php``. El contenido de este ficheró será::
  11. class Post extends AppModel {
  12. public $name = 'Post';
  13. }
  14. Los convenios usados para los nombres son importantes. Cuando llamamos a nuestro
  15. modelo *Post*, CakePHP deducirá automáticamente que este modelo se utilizará en
  16. el controlador PostsController, y que se vinculará a una tabla en nuestra base de
  17. datos llamada ``posts``.
  18. .. note::
  19. CakePHP creará dinámicamente un objeto para el modelo si no encuentra el
  20. fichero correspondiente en /app/Model. Esto significa que si te equivocas al
  21. nombrar el fichero (por ejemplo lo llamas post.php con la primera p
  22. minúscula o posts.php en plural) CakePHP no va a reconocer la configuración
  23. que escribas en ese fichero y utilizará valores por defecto.
  24. Para más información sobre modelos, como prefijos para las tablas, validación,
  25. etc. puedes visitar :doc:`/models` en el Manual.
  26. Crear un Controlador para nuestros Artículos (*Posts*)
  27. ======================================================
  28. Vamos a crear ahora un controlador para nuestros artículos. En el controlador es
  29. donde escribiremos el código para interactuar con nuestros artículos. Es donde
  30. se utilizan los modelos para llevar a cabo el trabajo que queramos hacer con
  31. nuestros artículos. Vamos a crear un nuevo fichero llamado
  32. ``PostsController.php`` dentro de la ruta ``/app/Controller``. El contenido de
  33. este fichero será::
  34. class PostsController extends AppController {
  35. public $helpers = array('Html','Form');
  36. }
  37. Y vamos a añadir una acción a nuestro nuevo controlador. Las acciones
  38. representan una función concreta o interfaz en nuestra aplicación. Por ejemplo,
  39. cuando los usuarios recuperan la url www.example.com/posts/index (que CakePHP
  40. también asigna por defecto a la ruta www.example.com/posts/ ya que la acción por
  41. defecto de cada controlador es index por convención) esperan ver un listado de
  42. *posts*. El código para tal acción sería este:
  43. ::
  44. class PostsController extends AppController {
  45. public $helpers = array ('Html','Form');
  46. function index() {
  47. $this->set('posts', $this->Post->find('all'));
  48. }
  49. }
  50. Si examinamos el contenido de la función index() en detalle, podemos ver que
  51. ahora los usuarios podrán acceder a la ruta www.example.com/posts/index. Además
  52. si creáramos otra función llamada ``foobar()``, los usuarios podrían acceder a
  53. ella en la url www.example.com/posts/foobar.
  54. .. warning::
  55. Puede que tengas la tentación de llamar tus controladores y acciones de
  56. forma determinada para que esto afecte a la ruta final, y así puedas
  57. predeterminar estas rutas. No te preocupes por esto ya que CakePHP
  58. incorpora un potente sistema de configuración de rutas. Al escribir los
  59. ficheros, te recomendamos seguir las convenciones de nombres y ser
  60. claro. Luego podrás generar las rutas que te convengan utilizando el
  61. componente de rutas (*Route*).
  62. La función index tiene sólo una instrucción ``set()`` que sirve para pasar
  63. información desde el controlador a la vista (*view*) asociada. Luego crearemos
  64. esta vista. Esta función set() asigna una nueva variab le 'posts' igual al valor
  65. retornado por la función ``find('all')`` del modelo ``Post``. Nuestro modelo
  66. Post está disponible automáticamente en el controlador y no hay que importarlo
  67. ya que hemos usado las convenciones de nombres de CakePHP.
  68. Para aprender más sobre los controladores, puedes visitar el capítulo
  69. :doc:`/controllers`
  70. Creando una vista para los artículos (*View*)
  71. =============================================
  72. Ya tenemos un modelo que define nuestros artículos y un controlador que ejecuta
  73. alguna lógica sobre ese modelo y envía los datos recuperados a la vista. Ahora
  74. vamos a crear una vista para la acción index().
  75. Las vistas en CakePHP están orientadas a cómo se van a presentar los datos. Las
  76. vistas encajan dentro de *layouts* o plantillas. Normalmente las vistas son una
  77. mezcla de HTML y PHP, aunque pueden ser también XML, CSV o incluso datos
  78. binarios.
  79. Las plantillas (*layouts*) sirven para recubrir las vistas y reutilizar código.
  80. Además pueden crearse tantos layouts como se deseen y se puede elegir cuál
  81. utilizar en cada momento. Por el momento vamos a usar el la plantilla por
  82. defecto ``default``.
  83. ¿ Recuerdas que el controlador envió a la vista una variable ``posts`` que
  84. contiene todos los posts mediante el método set() ? Esto nos generará una
  85. variable en la vista con esta pinta:
  86. ::
  87. // print_r($posts) output:
  88. Array
  89. (
  90. [0] => Array
  91. (
  92. [Post] => Array
  93. (
  94. [id] => 1
  95. [title] => The title
  96. [body] => This is the post body.
  97. [created] => 2008-02-13 18:34:55
  98. [modified] =>
  99. )
  100. )
  101. [1] => Array
  102. (
  103. [Post] => Array
  104. (
  105. [id] => 2
  106. [title] => A title once again
  107. [body] => And the post body follows.
  108. [created] => 2008-02-13 18:34:56
  109. [modified] =>
  110. )
  111. )
  112. [2] => Array
  113. (
  114. [Post] => Array
  115. (
  116. [id] => 3
  117. [title] => Title strikes back
  118. [body] => This is really exciting! Not.
  119. [created] => 2008-02-13 18:34:57
  120. [modified] =>
  121. )
  122. )
  123. )
  124. Las vistas en CakePHP se almacenan en la ruta ``/app/View`` y en un directorio
  125. con el mismo nombre que el controlador al que pertenecen, en nuestro caso
  126. *Posts*, así que para mostrar estos elementos formateados mediante una tabla
  127. tendremos algo como esto:
  128. .. code-block:: php
  129. <!-- File: /app/View/Posts/index.ctp -->
  130. <h1>Blog posts</h1>
  131. <table>
  132. <tr>
  133. <th>Id</th>
  134. <th>Title</th>
  135. <th>Created</th>
  136. </tr>
  137. <!-- Here is where we loop through our $posts array, printing out post info -->
  138. <?php foreach ($posts as $post): ?>
  139. <tr>
  140. <td><?php echo $post['Post']['id']; ?></td>
  141. <td>
  142. <?php echo $this->Html->link($post['Post']['title'],
  143. array('controller' => 'posts', 'action' => 'view', $post['Post']['id'])); ?>
  144. </td>
  145. <td><?php echo $post['Post']['created']; ?></td>
  146. </tr>
  147. <?php endforeach; ?>
  148. </table>
  149. Esto debería ser sencillo de comprender.
  150. Como habrás notado, hay una llamada a un objeto ``$this->Html``. Este objeto es
  151. una instancia de una clase *Helper* :php:class:`HtmlHelper`. CakePHP proporciona
  152. un conjunto de *Helpers* para ayudarte a completar acciones habituales, como por
  153. ejemplo realizar un link, crear un formulario, utilizar Javascript y Ajax de
  154. forma sencilla, etc. Puedes aprender más sobre esto en :doc:`/views/helpers` en
  155. otro momento. Basta con saber que la función ``link()`` generará un link HTML
  156. con el título como primer parámetro y la URL como segundo parámetro.
  157. Cuando crees URLs en CakePHP te recomendamos emplear el formato de array. Se
  158. explica con detenimiento en la sección de *Routes*. Si utilizas estas rutas,
  159. podrás aprovecharte de las potentes funcionalidades de generación inversa de
  160. rutas de CakePHP en el futuro. Además puedes especificar ritas relativas a la
  161. base de tu aplicación de la forma '/controlador/accion/param1/param2'.
  162. Llegados a este punto, deberías poder ver esta página si escribes la ruta a tu
  163. aplicación en el navegador, normalmente será algo asi
  164. http://localhost/blog/posts/index. Deberías ver los posts correctamente
  165. formateados en una tabla.
  166. Verás que si pinchas sobre alguno de los enlaces que aparecen en esta página
  167. (que van a una URL '/posts/view/some\_id', verás una página de error que te
  168. indica que la acción ``view()`` no ha sido definida todavía, y que debes
  169. definirla en el fichero PostsController. Si no ves ese error, algo ha ido mal,
  170. ya que esa acción no está definida y debería mostrar la página de error
  171. correspondiente. Cosa muy rara.
  172. Creemos esta acción para evitar el error::
  173. class PostsController extends AppController {
  174. public $helpers = array('Html', 'Form');
  175. public $name = 'Posts';
  176. public function index() {
  177. $this->set('posts', $this->Post->find('all'));
  178. }
  179. public function view($id = null) {
  180. $this->Post->id = $id;
  181. $this->set('post', $this->Post->read());
  182. }
  183. }
  184. Si observas la función view(), ahora el método set() debería serte familiar.
  185. Verás que estamos usando ``read()`` en vez de ``find('all')`` ya que sólo
  186. queremos un post concreto.
  187. Verás que nuestra función view toma un parámetro ($id), que es el ID del
  188. artículo que queremos ver. Este parámetro se gestiona automáticamente al llamar
  189. a la URL /posts/view/3, el valor '3' se pasa a la función view como primer
  190. parámetro $id.
  191. Vamos a definir la vista para esta nueva función, como hicimos antes para
  192. index() salvo que el nombre ahora será ``/app/View/Posts/view.ctp``.
  193. .. code-block:: php
  194. <!-- File: /app/View/Posts/view.ctp -->
  195. <h1><?php echo $post['Post']['title']?></h1>
  196. <p><small>Created: <?php echo $post['Post']['created']?></small></p>
  197. <p><?php echo $post['Post']['body']?></p>
  198. Verifica que ahora funciona el enlace que antes daba un error desde
  199. ``/posts/index`` o puedes ir manualmente si escribes ``/posts/view/1``.
  200. Añadiendo artículos (*posts*)
  201. =============================
  202. Ya podemos leer de la base de datos nuestros artículos y mostrarlos en pantalla,
  203. ahora vamos a ser capaces de crear nuevos artículos y guardarlos.
  204. Lo primero, añadir una nueva acción ``add()`` en nuestro controlador PostsController:
  205. ::
  206. class PostsController extends AppController {
  207. public $name = 'Posts';
  208. public $components = array('Session');
  209. public function index() {
  210. $this->set('posts', $this->Post->find('all'));
  211. }
  212. public function view($id) {
  213. $this->Post->id = $id;
  214. $this->set('post', $this->Post->read());
  215. }
  216. public function add() {
  217. if ($this->request->is('post')) {
  218. if ($this->Post->save($this->request->data)) {
  219. $this->Session->setFlash('Your post has been saved.');
  220. $this->redirect(array('action' => 'index'));
  221. }
  222. }
  223. }
  224. }
  225. .. note::
  226. Necesitas incluír el SessionComponent y SessionHelper en el controlador
  227. para poder utilizarlo. Si lo prefieres, puedes añadirlo en AppController
  228. y será compartido para todos los controladores que hereden de él.
  229. Lo que la función add() hace es: si el formulario enviado no está vacío, intenta
  230. guardar un nuevo artículo utilizando el modelo *Post*. Si no se guarda bien,
  231. muestra la vista correspondiente, así podremos mostrar los errores de validación
  232. si el artículo no se ha guardado correctamente.
  233. Cuando un usuario utiliza un formulario y efectúa un POST a la aplicación, esta
  234. información puedes accederla en ``$this->request->data``. Puedes usar la función
  235. :php:func:`pr()` o :php:func:`debug()` para mostrar el contenido de esa variable
  236. y ver la pinta que tiene.
  237. Utilizamos el SessionComponent, concretamente el método
  238. :php:meth:`SessionComponent::setFlash()` para guardar el mensaje en la sesión y
  239. poder recuperarlo posteriormente en la vista y mostrarlo al usuario, incluso
  240. después de haber redirigido a otra página mediante el método redirect(). Esto se
  241. realiza a través de la función :php:func:`SessionHelper::flash` que está en el
  242. layout, que muestra el mensaje y lo borra de la sesión para que sólo se vea una
  243. vez. El método :php:meth:`Controller::redirect <redirect>` del controlador nos
  244. permite redirigir a otra página de nuestra aplicación, traduciendo el parámetro
  245. ``array('action' => 'index)`` a la URL /posts, y la acción index. Puedes consultar
  246. la documentación de este método aquí :php:func:`Router::url()`. Verás los
  247. diferentes modos de indicar la ruta que quieres construir.
  248. Al llamar al método ``save()``, comprobará si hay errores de validación primero
  249. y si encuentra alguno, no continuará con el proceso de guardado. Veremos a
  250. continuación cómo trabajar con estos errores de validación.
  251. Validando los datos
  252. ===================
  253. CakePHP te ayuda a evitar la monotonía al construir tus formularios y su
  254. validación. Todos odiamos teclear largos formularios y gastar más tiempo en
  255. reglas de validación de cada campo. CakePHP está aquí para echarnos una mano.
  256. Para aprovechar estas funciones es conveniente que utilices el FormHelper en tus
  257. vistas. La clase :php:class:`FormHelper` está disponible en tus vistas por
  258. defecto mediante llamadas del estilo ``$this->Form``.
  259. Nuestra vista sería así
  260. .. code-block:: php
  261. <!-- File: /app/View/Posts/add.ctp -->
  262. <h1>Add Post</h1>
  263. <?php
  264. echo $this->Form->create('Post');
  265. echo $this->Form->input('title');
  266. echo $this->Form->input('body', array('rows' => '3'));
  267. echo $this->Form->end('Save Post');
  268. ?>
  269. Hemos usado FormHelper para generar la etiqueta 'form'. Esta llamada al
  270. FormHelper : ``$this->Form->create()`` generaría el siguiente código
  271. .. code-block:: html
  272. <form id="PostAddForm" method="post" action="/posts/add">
  273. Si ``create()`` no tiene parámetros al ser llamado, asume que estás creando un
  274. formulario que realiza el *submit* al método del controlador ``add()`` o al
  275. método ``edit()`` si hay un ``id`` en los datos del formulario. Por defecto el
  276. formulario se enviará por POST.
  277. Las llamadas ``$this->Form->input()`` se usan para crear los elementos del
  278. formulario con el nombre que se pasa por parámetro. El primer parámetro indica
  279. precisamente el nombre del campo del modelo para el que se quiere crear el
  280. elemento de entrada. El segundo parámetro te permite definir muchas otras
  281. variables sobre la forma en la que se generará este *input field*. Por ejemplo,
  282. al enviar ``array('rows' => '3')`` estamos indicando el número de filas para el
  283. campo textarea que vamos a generar. El método input() está dotado de
  284. introspección y un poco de magia, ya que tiene en cuenta el tipo de datos del
  285. modelo al generar cada campo.
  286. Una vez creados los campos de entrada para nuestro modelo, la llamada
  287. ``$this->Form->end()`` genera un botón de *submit* en el formulario y cierra el
  288. tag <form>. Puedes ver todos los detalles aquí :doc:`/views/helpers`.
  289. Volvamos atrás un minuto para añadir un enlace en ``/app/View/Post/index.ctp``
  290. que nos permita agregar nuevos artículos. Justo antes del tag <table> añade la
  291. siguiente línea::
  292. echo $this->Html->link('Add Post', array('controller' => 'posts', 'action' => 'add'));
  293. Te estarás preguntando: ¿ Cómo le digo a CakePHP la forma en la que debe validar
  294. estos datos ? Muy sencillo, las reglas de validación se escriben en el modelo.
  295. Abre el modelo Post y vamos a escribir allí algunas reglas sencillas ::
  296. class Post extends AppModel {
  297. public $name = 'Post';
  298. public $validate = array(
  299. 'title' => array(
  300. 'rule' => 'notEmpty'
  301. ),
  302. 'body' => array(
  303. 'rule' => 'notEmpty'
  304. )
  305. );
  306. }
  307. El array ``$validate`` contiene las reglas definidas para validar cada campo,
  308. cada vez que se llama al método save(). En este caso vemos que la regla para
  309. ambos campos es que no pueden ser vacíos ``notEmpty``. El conjunto de reglas de
  310. validación de CakePHP es muy potente y variado. Podrás validar direcciones de
  311. email, codificación de tarjetas de crédito, incluso añadir tus propias reglas de
  312. validación personalizadas. Para más información sobre esto
  313. :doc:`/models/data-validation`.
  314. Ahora que ya tienes las reglas de validación definidas, usa tu aplicación para
  315. crear un nuevo artículo con un título vacío y verás cómo funcionan. Como hemos
  316. usado el método :php:meth:`FormHelper::input()`, los mensajes de error se
  317. construyen automáticamente en la vista sin código adicional.
  318. Editando Posts
  319. ==============
  320. Seguro que ya le vas cogiendo el truco a esto. El método es siempre el mismo:
  321. primero la acción en el controlador, luego la vista.
  322. Aquí está el método edit():
  323. ::
  324. public function edit($id = null) {
  325. if (!$id) {
  326. throw new NotFoundException(__('Invalid post'));
  327. }
  328. $post = $this->Post->findById($id);
  329. if (!$post) {
  330. throw new NotFoundException(__('Invalid post'));
  331. }
  332. if ($this->request->is(array('post', 'put'))) {
  333. $this->Post->id = $id;
  334. if ($this->Post->save($this->request->data)) {
  335. $this->Session->setFlash(__('Your post has been updated.'));
  336. return $this->redirect(array('action' => 'index'));
  337. }
  338. $this->Session->setFlash(__('Unable to update your post.'));
  339. }
  340. if (!$this->request->data) {
  341. $this->request->data = $post;
  342. }
  343. }
  344. Esta acción primero comprueba que se trata de un GET request. Si lo es, buscamos
  345. un *Post* con el id proporcionado como parámetro y lo ponemos a disposición para
  346. usarlo en la vista. Si la llamada no es GET, usaremos los datos que se envíen
  347. por POST para intentar actualizar nuestro artículo. Si encontramos algún error
  348. en estos datos, lo enviaremos a la vista sin guardar nada para que el usuario
  349. pueda corregirlos.
  350. La vista quedará así:
  351. .. code-block:: php
  352. <!-- File: /app/View/Posts/edit.ctp -->
  353. <h1>Edit Post</h1>
  354. <?php
  355. echo $this->Form->create('Post', array('action' => 'edit'));
  356. echo $this->Form->input('title');
  357. echo $this->Form->input('body', array('rows' => '3'));
  358. echo $this->Form->input('id', array('type' => 'hidden'));
  359. echo $this->Form->end('Save Post');
  360. Mostramos el formulario de edición (con los valores actuales de ese artículo),
  361. junto a los errores de validación que hubiese.
  362. Una cosa importante, CakePHP asume que estás editando un modelo si su ``id``
  363. está presente en su array de datos. Si no hay un 'id' presente, CakePHP asumirá
  364. que es un nuevo elemento al llamar a la función ``save()``. Puedes actualizar un
  365. poco tu vista 'index' para añadir los enlaces de edición de un artículo
  366. específico:
  367. .. code-block:: php
  368. <!-- File: /app/View/Posts/index.ctp (edit links added) -->
  369. <h1>Blog posts</h1>
  370. <p><?php echo $this->Html->link("Add Post", array('action' => 'add')); ?></p>
  371. <table>
  372. <tr>
  373. <th>Id</th>
  374. <th>Title</th>
  375. <th>Action</th>
  376. <th>Created</th>
  377. </tr>
  378. <!-- Here's where we loop through our $posts array, printing out post info -->
  379. <?php foreach ($posts as $post): ?>
  380. <tr>
  381. <td><?php echo $post['Post']['id']; ?></td>
  382. <td>
  383. <?php echo $this->Html->link($post['Post']['title'], array('action' => 'view', $post['Post']['id']));?>
  384. </td>
  385. <td>
  386. <?php echo $this->Form->postLink(
  387. 'Delete',
  388. array('action' => 'delete', $post['Post']['id']),
  389. array('confirm' => 'Are you sure?')
  390. )?>
  391. <?php echo $this->Html->link('Edit', array('action' => 'edit', $post['Post']['id']));?>
  392. </td>
  393. <td><?php echo $post['Post']['created']; ?></td>
  394. </tr>
  395. <?php endforeach; ?>
  396. </table>
  397. Borrando Artículos
  398. ==================
  399. Vamos a permitir a los usuarios que borren artículos. Primero, el método en
  400. nuestro controlador:
  401. ::
  402. function delete($id) {
  403. if (!$this->request->is('post')) {
  404. throw new MethodNotAllowedException();
  405. }
  406. if ($this->Post->delete($id)) {
  407. $this->Session->setFlash('The post with id: ' . $id . ' has been deleted.');
  408. $this->redirect(array('action' => 'index'));
  409. }
  410. }
  411. Este método borra un artículo cuyo 'id' enviamos como parámetro y usa
  412. ``$this->Session->setFlash()`` para mostrar un mensaje si ha sido borrado. Luego
  413. redirige a '/posts/index'. Si el usuario intenta borrar un artículo mediante una
  414. llamada GET, generaremos una excepción. Las excepciónes que no se traten, serán
  415. procesadas por CakePHP de forma genérica, mostrando una bonita página de error.
  416. Hay muchas excepciones a tu disposición :doc:`/development/exceptions` que
  417. puedes usar para informar de diversos problemas típicos.
  418. Como estamos ejecutando algunos métodos y luego redirigiendo a otra acción de
  419. nuestro controlador, no es necesaria ninguna vista (nunca se usa). Lo que si
  420. querrás es actualizar la vista index.ctp para incluír el ya habitual enlace:
  421. .. code-block:: php
  422. <!-- File: /app/View/Posts/index.ctp -->
  423. <h1>Blog posts</h1>
  424. <p><?php echo $this->Html->link('Add Post', array('action' => 'add')); ?></p>
  425. <table>
  426. <tr>
  427. <th>Id</th>
  428. <th>Title</th>
  429. <th>Actions</th>
  430. <th>Created</th>
  431. </tr>
  432. <!-- Here's where we loop through our $posts array, printing out post info -->
  433. <?php foreach ($posts as $post): ?>
  434. <tr>
  435. <td><?php echo $post['Post']['id']; ?></td>
  436. <td>
  437. <?php echo $this->Html->link($post['Post']['title'], array('action' => 'view', $post['Post']['id']));?>
  438. </td>
  439. <td>
  440. <?php echo $this->Form->postLink(
  441. 'Delete',
  442. array('action' => 'delete', $post['Post']['id']),
  443. array('confirm' => 'Are you sure?'));
  444. ?>
  445. </td>
  446. <td><?php echo $post['Post']['created']; ?></td>
  447. </tr>
  448. <?php endforeach; ?>
  449. </table>
  450. .. note::
  451. Esta vista utiliza el FormHelper para pedir confirmación al usuario
  452. antes de borrar un artículo. Además el enlace para borrar el artículo se
  453. construye con Javascript para que se realice una llamada POST.
  454. Rutas (*Routes*)
  455. ================
  456. En muchas ocasiones, las rutas por defecto de CakePHP funcionan bien tal y como
  457. están. Los desarroladores que quieren rutas diferentes para mejorar la
  458. usabilidad apreciarán la forma en la que CakePHP relaciona las URLs con las
  459. acciones de los controladores. Vamos a hacer cambios ligeros para este tutorial.
  460. Para más información sobre las rutas, visita esta referencia
  461. :ref:`routes-configuration`.
  462. Por defecto CakePHP responde a las llamadas a la raíz de tu sitio (por ejemplo
  463. www.example.com/) usando el controlador PagesController, y la acción
  464. 'display'/'home'. Esto muestra la página de bienvenida con información de
  465. CakePHP que ya has visto. Vamos a cambiar esto mediante una nueva regla.
  466. Las reglas de enrutamiento están en ``/app/Config/routes.php``. Comentaremos
  467. primero la regla de la que hemos hablado:
  468. ::
  469. Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
  470. Como habíamos dicho, esta regla conecta la URL '/' con el controlador 'pages' la
  471. acción 'display' y le pasa como parámetro 'home', así que reemplazaremos esta
  472. regla por esta otra:
  473. ::
  474. Router::connect('/', array('controller' => 'posts', 'action' => 'index'));
  475. Ahora la URL '/' nos llevará al controlador 'posts' y la acción 'index'.
  476. .. note::
  477. CakePHP también calcula las rutas a la inversa. Si en tu código pasas el
  478. array ``array('controller' => 'posts', 'action' => 'index')`` a una
  479. función que espera una url, el resultado será '/'. Es buena idea usar
  480. siempre arrays para configurar las URL, lo que asegura que los links
  481. irán siempre al mismo lugar.
  482. Conclusión
  483. ==========
  484. Creando aplicaciones de este modo te traerá paz, amor, dinero a carretas e
  485. incluso te conseguirá lo demás que puedas querer. Así de simple.
  486. Ten en cuenta que este tutorial es muy básico, CakePHP tiene *muchas* otras
  487. cosas que harán tu vida más fácil, y es flexible aunque no hemos cubierto aquí
  488. estos puntos para que te sea más simple al principio. Usa el resto de este
  489. manual como una guía para construir mejores aplicaciones (recuerda todo los los
  490. beneficios que hemos mencionado un poco más arriba)
  491. Ahora ya estás preparado para la acción. Empieza tu propio proyecto, lee el
  492. resto del manual y el API `Manual </>`_ `API <http://api20.cakephp.org>`_.
  493. Lectura sugerida para continuar desde aquí
  494. ==========================================
  495. 1. :ref:`view-layouts`: Personaliza la plantilla *layout* de tu aplicación
  496. 2. :ref:`view-elements` Incluír vistas y reutilizar trozos de código
  497. 3. :doc:`/controllers/scaffolding`: Prototipos antes de trabajar en el código final
  498. 4. :doc:`/console-and-shells/code-generation-with-bake` Generación básica de CRUDs
  499. 5. :doc:`/core-libraries/components/authentication`: Gestión de usuarios y permisos