Publi

Creando un controlador en Magento (paso a paso)


Hace un tiempo comentábamos cómo crear un plugin para Magento. Ahora, vamos a completar ese plugin creando un controlador (y nos metermos ligeramente con las plantillas) para crear algo funcional dentro de nuestra instalación de Magento.

Antes de nada, advertir que el tema de las mayúsculas y minúsculas tanto en nombres de archivos como nombres de módulos es un poco delicado, por lo que si queremos curarnos en salud, debemos elegir un nombre lo más sencillo posible. Y, sobre todo, mientras estés trabajando desactiva cachés o, al menos, bórralos a menudo. Vamos a estar haciendo cambios constantemente y tal vez no aparezcan por eso.

Creando un controlador

Esta es la parte más sencilla. Sólo tenemos que crear en el directorio de nuestro plugin el directorio «controllers» en minúscula. Si en el post anterior veíamos que nuestro módulo estaba en app/code/local/nuestraEmpresa/nuestroModulo/ , debemos crear app/code/local/nuestraEmpresa/nuestroModulo/controllers.
. En el ejemplo la empresa se llamará Poesia y el Plugin HolaMundo (aprovechamos y metemos una mayúscula, para ver cómo podemos hacerlo).

Lo primero será editar el archivo de configuración de nuestro plugin app/code/local/nuestraEmpresa/nuestroModulo/etc/config.xml, he incluido el archivo completo con una nota en la que podemos ver las líneas nuevas:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?xml version="1.0" encoding="UTF-8"?>
<!--
Opcionalmente podemos poner un comentario contando qué hace nuestro módulo, nuestra web,
información sobre la licencia, etc
-->
<config>
    <modules>
        <Poesia_HolaMundo> <!-- namespace_modulo -->

            <!-- Esta es la versión de nuestro módulo -->
            <version>0.0.1</version>

        </Poesia_HolaMundo>
    </modules>
<!-- Lo que necesitamos para utilizar los controladores -->
    <frontend>
      <routers>
    <holaMundo>
      <use>standard</use>
      <args>
        <module>Poesia_HolaMundo</module>
        <frontName>hm</frontName>
      </args>
    </holaMundo>
      </routers>
    </frontend>
<!-- Lo que necesitamos para utilizar los controladores -->
</config>

En este caso, la etiqueta <holaMundo> corresponde con el nombre de nuestro módulo, aunque la primera sea mayúscula, aquí empezará en minúscula (camelCase empezando en minúscula). Luego, dentro de <args> el módulo, es NuestraEmpresa_NuestroModulo y el frontname será el nombre de nuestro módulo en la URL. Por lo tanto todos los controladores estarán a partir de http://urldenuestromagento.ext/hm/xxx.

Dentro de controllers creamos un archivo que se llama nuestrocontroladorController.php. En el ejemplo, como queremos hacer un sistema de postventa, lo llamaremos PostVentaController.php. Ese archivo debe extender Mage_Core_Controller_Front_Action (podemos extender otros para algunos casos especiales). Dentro de los controladores, crearemos acciones, debemos pensar que un controlador puede lanzar varios tipos de acciones, por ejemplo, un controlador para un formulario podría querer lanzar la vista del formulario (precargando algunos valores), luego procesar los datos enviados y validar las entradas del usuario por AJAX, por lo que tendríamos tres acciones (por supuesto que podemos tener una sola acción, pero separamos nuestro código y diferenciamos bien las partes).

Las acciones, por defecto se llamarán cuando accedamos a http://urldenuestromagento.ext/plugin/controlador/accion y éstas llamarán a un método de nuestra clase controlador (PostVentaController). En principio, vamos a definir una acción especial que se cargará cuando hagamos http://urldenuestromagento.ext/plugin/controlador/ que será la IndexAction. En este ejemplo, crearemos un controlador con dos métodos, el indexAction y el testAction para http://urldenuestromagento.ext/plugin/controlador/ y http://urldenuestromagento.ext/plugin/controlador/test respectivamente.

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
class Poesia_HolaMundo_PostVentaController extends Mage_Core_Controller_Front_Action
{
  function indexAction()
  {
    echo "Estamos en el index";
  }

  function testAction()
  {
    echo "Estamos en test";
  }
}

Si accedemos a las URLs anteriormente mencionadas veremos que los controladores se cargan bien. Aunque sólo se cargan esos controladores, sin plantillas ni bloques ni nada. Por lo que debemos trabajar un poco más. En nuestro ejemplo del módulo PostVenta, podremos acceder a http://urldenuestromagento.ext/hm/postVenta/ o a http://urldenuestromagento.ext/hm/PostVenta/ aunque no a http://urldenuestromagento.ext/hm/postventa/.

Haciendo que nuestras acciones usen plantillas

Para empezar con nuestras plantillas. Vamos a hacer una configuración completa del sistema, creando un nuevo archivo de layout (podemos aprovechar alguno de los que ya existen, pero lo suyo es que todo quede bien separado y diferenciado, ya que el módulo debe ser totalmente independiente).

Volvemos a editar el archivo app/code/local/nuestraEmpresa/nuestroModulo/etc/config.xml para decirle que busque nuestro archivo XML de layout, que se llamará poesia.xml (pego el archivo entero, pero tendremos un comentario que indicará las novedades):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?xml version="1.0" encoding="UTF-8"?>
<!--
Opcionalmente podemos poner un comentario contando qué hace nuestro módulo, nuestra web,
información sobre la licencia, etc
-->
<config>
    <modules>
        <Poesia_HolaMundo> <!-- namespace_modulo -->

            <!-- Esta es la versión de nuestro módulo -->
            <version>0.0.1</version>

        </Poesia_HolaMundo>
    </modules>
    <frontend>
<!-- Lo que necesitamos para utilizar los controladores -->
      <routers>
    <holaMundo>
      <use>standard</use>
      <args>
        <module>Poesia_HolaMundo</module>
        <frontName>hm</frontName>
      </args>
    </holaMundo>
      </routers>
<!-- Lo que necesitamos para utilizar los controladores -->
<!-- Lo que necesitamos para el layout y las plantillas -->
      <layout>
        <updates>
      <holamund>
        <file>poesia.xml</file>
      </holamundo>
        </updates>
      </layout>
<!-- Lo que necesitamos para el layout y las plantillas -->
    </frontend>
</config>

En este caso, el tag <holamundo> indicará el módulo al que se hace referencia (¡todo en minúsculas esta vez!)

El archivo de layout lo podemos crear válido para todos los temas o sólo para un tema particular, dependiendo si está en app/design/frontend/base/default/layout/poesia.xml o si lo colocamos en app/design/frontend/default/nuestrotema/layout/poesia.xml; si el archivo se encuentra en los dos sitios, se cogerá el específico para el tema. Es más, en ese poesia.xml se pueden llamar plantillas que se buscarán en app/design/frontend/default/nuestrotema/, pero si no se encuentran ahí, se buscarán en app/design/frontend/base/default/.

Vamos a crear un archivo poesia.xml básico:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0"?>
<layout version="0.1.0">
    <default>
    <reference name="root">
        <action method="setTemplate">
        <template>page/1column.phtml</template>
        </action>
    </reference>
    <reference name="content">
      <block type="core/template" name="main_block" template="holamundo/index.phtml"></block>
    </reference>
      </default>
</layout>

Aquí especificamos que la plantilla base para nuestras páginas será page/1column.phtml (podemos buscarla en base o en nuestro tema). También decimos que el contenido contendrá un bloque básico (core/template) cuya plantilla será holamundo/index.phtml.

Ahora tenemos que decirle a las acciones de nuestro controlador que deben cargar la plantilla:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
class Poesia_HolaMundo_PostVentaController extends Mage_Core_Controller_Front_Action
{
  function indexAction()
  {
    $this->loadLayout();    
    $this->renderLayout();
  }

  function testAction()
  {
    $this->loadLayout();    
    $this->renderLayout();
   }
}

Ahora, tanto test, como index, cargarán la plantilla básica y sus contenidos, ya es cosa vuestra programar las acciones. Aunque, ahora mismo los dos están utilizando la misma plantilla que podrá estar en app/design/frontend/base/default/template/holamundo/index.phtml o en app/design/frontend/default/tema/template/holamundo/index.phtml

Personalizando las plantillas de nuestras acciones

Si queremos que cada acción utilice una plantilla diferente, debemos especificarlo en el xml de layout, en nuestro caso, poesia.xml de la sigueinte manera:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0"?>
<layout version="0.1.0">
  <holamundo_postventa_index>
    <reference name="root">
      <action method="setTemplate">
    <template>page/1column.phtml</template>
      </action>
    </reference>
    <reference name="content">
      <block type="core/template" name="main_block" template="holamundo/index.phtml"></block>
    </reference>
  </holamundo_postventa_index>
  <holamundo_postventa_test>
    <reference name="root">
      <action method="setTemplate">
    <template>page/2columns-left.phtml</template>
      </action>
    </reference>
    <reference name="content">
      <block type="core/template" name="main_block" template="holamundo/test.phtml"></block>
    </reference>
  </holamundo_postventa_test>
</layout>

En este caso, el nombre del plugin, controlador y acción tiene que ir completamente en minúsculas. Aquí hemos utilizado una plantilla base (root) diferente para cada acción, pero podemos utilizar una plantilla común y variar sólo el content:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0"?>
<layout version="0.1.0">
  <default>
    <reference name="root">
      <action method="setTemplate">
    <template>page/1column.phtml</template>
      </action>
    </reference>
  </default>
  <holamundo_postventa_index>
    <reference name="content">
      <block type="core/template" name="main_block" template="holamundo/index.phtml"></block>
    </reference>
  </holamundo_postventa_index>
  <holamundo_postventa_test>
    <reference name="content">
      <block type="core/template" name="main_block" template="holamundo/test.phtml"></block>
    </reference>
  </holamundo_postventa_test>
</layout>

Además, podemos incluir CSS o JS personalizados, que podrán ser cargados en la parte superior de la página:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?xml version="1.0"?>
<layout version="0.1.0">
  <default>
    <reference name="head">
      <!-- CSS y JS propios -->
      <action method="addJs">
        <script>holamundo/holamundo.js</script> <!-- se buscará en [magentoroot]/js -->
      </action>

      <action method="addCss">
    <!-- se buscará en [magentoroot]/skin/frontend/default/[tema]/css/ -->
    <!-- o en [magentoroot]/skin/frontend/base/default/css/ -->
        <stylesheet>css/holamundo.css</stylesheet>
      </action>
    </reference>
    <reference name="root">
      <action method="setTemplate">
    <template>page/1column.phtml</template>
      </action>
    </reference>
  </default>
  <holamundo_postventa_index>
    <reference name="content">
      <block type="core/template" name="main_block" template="holamundo/index.phtml"></block>
    </reference>
  </holamundo_postventa_index>
  <holamundo_postventa_test>
    <reference name="content">
      <block type="core/template" name="main_block" template="holamundo/test.phtml"></block>
    </reference>
  </holamundo_postventa_test>
</layout>

Chuleta rápida para respuestas de acciones

Este pequeño anexo nos ayudará a generar posibles respuestas de diferente índole desde nuestras acciones. Por ejemplo:

Devolver un 404

Esto nos sirve, por ejemplo para evitar que el usuario vea que ahí hay algo. Tal vez sea un método que sólo determinados usuarios pueden utilizar, o que usamos sólo en modo desarrollo, por ejemplo nuestro indexAction() se quedaría así:

1
2
3
4
  function indexAction()
  {
    $this->norouteAction();
  }

y evitaremos que alguien entre directamente a esa acción.

Devolver mensajes de éxito, error o advertencia

Para esto, tenemos que hacer lo siguiente:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
class Poesia_HolaMundo_PostVentaController extends Mage_Core_Controller_Front_Action
{
  function indexAction()
  {
    Mage::getSingleton('core/session')->addSuccess($this->__('Esto devolverá éxito'));
    $this->loadLayout();    
    $this->renderLayout();
  }

  function testAction()
  {
    Mage::getSingleton('core/session')->addWarning($this->__('Esto devolverá advertencia'));
    $this->loadLayout();    
    $this->renderLayout();
   }

  function errorAction()
  {
    Mage::getSingleton('core/session')->addError($this->__('Esto devolverá error'));
    $this->loadLayout();    
    $this->renderLayout();
   }
}

Warning! En algunos temas, los estilos de Warning no están definidos.
Es una buena técnica utilizar el método $this->__() ante cualquier mensaje que demos, ya que lo haremos pasar por el traductor y podrá ponerse en cualquier idioma (siempre que nos curremos las traducciones).

Redirecciones

Basta con llamar a $this->_redirectUrl() con la dirección que queremos llamar (esto casi casi puede dar para otro post):

1
2
3
4
  function errorAction()
  {
    $this->_redirectUrl('http://la_url_que_quiero.com/');
   }

o por ejemplo:

1
2
3
4
  function errorAction()
  {
    $this->_redirectUrl(Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB));
   }

para redirigir a la página principal de la tienda.

Una ayuda es sacar la URL desde la que venimos con: Mage::helper(‘core/http’)->getHttpReferer();

Conocer la petición

Por último, un detalle importante es conocer la petición que ha hecho el usuario cuando ha cargado la página. Por ejemplo, si ha enviado un formulario. Siguiendo este supuesto, dentro del controlador podemos cargar dicha petición en un objecto, ver si es una petición tipo POST y analizar algún parámetro enviado con dicho método:

1
2
3
4
5
6
7
8
  function sendFormAction()
  {
    $request = $this->getRequest();
    if (!$request->isPost())
       return $this->_redirectUrl(Mage::getBaseUrl());
   
    $parametropost = $request->getPost('nombreparametro');
  }

También podría interesarte....

There are 7 comments left Ir a comentario

  1. Pingback: Creando un controlador en Magento (paso a paso) | PlanetaLibre /

  2. Marc /
    Usando Mozilla Firefox Mozilla Firefox 48.0 en Ubuntu Linux Ubuntu Linux

    Genial! Muchas gracias por tu tiempo en hacer la guía 🙂

    1. Gaspar Fernández / Post Author
      Usando Mozilla Firefox Mozilla Firefox 48.0 en Ubuntu Linux Ubuntu Linux

      Muchas gracias por tu comentario! Espero que te haya sido de ayuda, y si has hecho algún trabajo derivado, compártelo, me gustaría verlo 🙂

  3. Pingback: Primeras decisiones para crear tu tienda online con WooCommerce – Poesía Binaria /

Leave a Reply