Añadir páginas a Magento desde una extensión

Añadir páginas a Magento desde una extensión

azul-3Si hace unos días aprendíamos a crear un módulo para Magento, hoy nos toca aprender a hacer nuevas páginas para Magento. Os diría de forma intuitiva y simple, pero para qué os voy a engañar…

Venga va, en serio. Crear nuevas páginas para Magento es simple, siempre y cuando tengas una mente bien estructurada, capaz de enlazar diferentes puntos de diferentes archivos entre sí, creando una compleja red de relaciones, sobre todo si, como en el caso que vamos a ver, la cosa se complica. Si no la tienes, no te preocupes, que intentaré hacerlo lo más simple posible.

Recientemente hemos tenido que crear una página nueva en un sistema Magento, accesible a través del área de cliente “Mi cuenta”. Así que lo vamos a usar como ejemplo para desarrollar este tema.

Vamos por pasos. Os recomiendo que leáis primero la entrada anterior, sobre cómo crear un módulo para Magento, ya que voy a trabajar sobre ese ejemplo. Vamos a crear una página accesible desde “Mi cuenta”, que nos muestre el archivo de log que generamos cada vez que un fichero se modifica. ¿No le véis utilidad? Bueno, yo tampoco, pero lo importante no es la utilidad que tiene un módulo de ejemplo, si no que aprendáis cómo hacer vuestros propios módulos.

Modificando el config.xml para que acepte nuestra ruta

Nuestra página será accesible desde una dirección con este patrón <urlbase>/<nombredelmodulo>/<pagina>, donde urlbase es la url de nuestra tienda, y nombredelmodulo es el nombre de nuestro módulo. Algo como http://urldelatienda.com/mimodulo/index, por ejemplo.

Esto no va a ocurrir por arte de magia. Va a ocurrir porque lo vamos a especificar en una redirección en nuestro archivo config.xml (en la carpeta etc de nuestro módulo).

La última vez añadimos la etiqueta global aquí, englobando todo nuestro código. Bien, vamos justo donde acaba, después de </global> y antes de </config>, y escribimos esto:

	<frontend>
		<routers>
			<controldeproductos>
				<use>standard</use>
				<args>
					<module>Codigonexo_ControlDeProductos</module>
					<frontName>controldeproductos</frontName>
				</args>
			</controldeproductos>
		</routers>
		<layout>
			<updates>
				<codigonexo_controldeproductos>
					<file>codigonexo_controldeproductos.xml</file>
				</codigonexo_controldeproductos>
			</updates>
		</layout>
	</frontend>

De acuerdo, vamos por partes.

Hemos añadido la etiqueta <frontend>, que denota que vamos a actuar sobre la parte [def]front end[/def] de la aplicación. Dentro, dos etiquetas: routers y layout.

<routers> es la etiqueta que nos va a servir de redireccionador. Establecemos en <module> el nombre completo del módulo, con la carpeta de la compañía y la carpeta del módulo, separados por un guión bajo. En frontName especificamos el nombre que queremos tener en la ruta (que será el mismo de la etiqueta que engloba todo esto dentro de <routers>).

<layout> define el archivo de Layout que se va a cargar cuando accedamos a esta página. Este archivo debe estar siempre en la carpeta Layout del tema que estemos usando. Nosotros usamos design/frontend/base/default. Aquí, en la carpeta Layout, crearemos nuestro archivo de layout, codigonexo_controldeproductos.xml.

Antes de pasar al Layout, nos falta una cosa más en nuestro config.xml. Dentro de los eventos, hay que definir un nuevo observador:

			<controller_action_layout_load_before>
				<observers>
					<codigonexo_controldeproductos>
						<type>singleton</type>
						<class>codigonexo_controldeproductos/observer</class>
						<method>showLogLink</method>
					</codigonexo_controldeproductos>
				</observers>
			</controller_action_layout_load_before>

Esto define una nueva acción que hay que incluir, evidentemente, en nuestro archivo Codigonexo/ControlDeProductos/Model/Observer.php:

     public function showLogLink(Varien_Event_Observer $observer){
         if(Mage::getSingleton('customer/session')->isLoggedIn() ){  // Solo si el usuario esta logueado
             // Código que gestiona si un usuario puede acceder o no al enlace.
             if(/*CONDICION*/){
                 $update->addHandle('customer_controldeproductos_link');
             }

         }
     }

Así, ahora, dependiendo de vuestro código y condiciones, el enlace se mostrará a todos o solo a una serie de usuarios.  Si no queréis condiciones, simplemente dejad la linea de $update->addHandle(‘<customer_controldeproductos_link>’); ¿Qué es esto? Lo vamos a ver enseguida.

El Layout

Este archivo es el que modifica los datos que aparecen en pantalla según le digamos. Por lo pronto, vamos a crearlo y a copiar el código, luego lo explico.

<?xml version="1.0" encoding="UTF-8"?>

<layout version="0.1.0">

        <!-- Lo primero es añadir un enlace en el menu de navegación -->

        <!-- Este es el nombre que veíamos en Observer.php -->
	<customer_controldeproductos_link>
	    <reference name="customer_account_navigation">
	            <action method="addLink" translate="label">
                        <!-- Los atributos del enlace. Es importante saber que 'path' define la segunda parte de la url -->
	            	<name>controldeproductos</name>
	            	<path>controldeproductos/log</path>
	            	<label>Control de Productos</label>
	            	<update handle='customer_account'/>
            	</action>
	    </reference>
	</customer_controldeproductos_link>

        <!-- Ahora ya nos centramos en nuestra página nueva -->

	<controldeproductos_log_index translate="label">
		<label>Control de Productos</label>
        <update handle="customer_account"/>
        <reference name="my.account.wrapper">
                <!-- Importante que recordemos el name y el template del bloque -->
        	<block type="page/html" name="controldeproductos_log" template="codigonexo_controldeproductos/log.phtml" />
        </reference>
	</controldeproductos_list_index>

</layout>

Como ya podéis ver en los comentarios, en primer lugar se define el nuevo enlace. El atributo <path> define la parte <nombredelmodulo>/<pagina> de nuestro patron para url: <urlbase>/<nombredelmodulo>/<pagina>.

Es importante saber que <update handle=’customer_account’/> es la etiqueta que hace que todo esto actue sobre la página de usuario.

Para nuestra página, creamos una etiqueta nueva (controldeproductos_log_index, por ejemplo). Es importante que tengamos una referencia, que en este caso es “my.account.wrapper”, o nuestro código no aparecerá en ningún sitio. En el <block>, el name y el template son importantes, ya que definen el nombre del bloque que estamos cargando, y la plantlla que se utilizará. La plantilla hay que crearla en /design/frontend/base/default/template.

El template

El archivo template lo crearemos con extensión .phtml dentro de la carpeta que ya hemos indicado. Su contenido es, básicamente, el html (generado o no con php) que se mostrará al entrar en la página.

Nosotros vamos a mostrar el contenido del archivo var/log/product-updates.log, que de eso se trata este ejemplo.

<?php
    $logfile = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB)."var/log/product-updates.log";
    $loghtml = "";
    if($logfile){
        $loghtml = file_get_contents($logfile);
    }
?>
<div class="block block-codigonexo_controldeproductos">
    <div class="block-title">
        <strong><span>Log de Control de Productos</span></strong>
    </div>
    <div id='log_content'>
        <?=$loghtml;?>
    </div>
</div>

Todo esto es muy bonito… pero como habréis podido comprobar, aun no funciona.

No basta con un template y un layout. Necesitamos un archivo más que conecte todo esto. Necesitamos el Controlador.

El Controller

Lo último que nos queda por hacer es crear un archivo llamado “controller” o controlador, que representará nuestro Layout cuando accedamos a la pagina.

El controlador estará en nuestro módulo, en la carpeta “controllers” (por increible que parezca, esta vez sí, en minúsculas), y se debe llamar como la acción que queremos ejecutar. En este caso: LogController.php.

Dentro vamos a definir una clase nueva, cuyo nombre debe ser Empresa_Modulo_AcciónController. En nuestro caso, Codigonexo_ControlDeProductos_LogController. Evidentemente, podemos definir las funciones que necesitemos, pero hay al menos dos que no pueden faltar: la función que ejecuta la acción, llamada con el nombre de la acción seguido de Action, y la función indexAction.

<?php

class Codigonexo_ControlDeProductos_LogController extends Mage_Core_Controller_Front_Action
{

    public function logAction(){
        $this->loadLayout();
        $this->getLayout()->getBlock('controldeproductos_log')->setTitle('Control de Productos');
        $this->renderLayout();
    }

    public function indexAction(){
        $this->logAction();
    }
}

?>

¿Recordáis el <block> que definimos en el layout? Pues el atributo name de ese block es el parámetro que debemos pasar en la función getBlock.

La segunda, indexAction, es la que se encarga de que la dirección sea simplemente “controldeproductos/log”.

Si ahora accedéis desde un usuario cliente a la sección “Mi Cuenta”, os debería aparecer un enlace más en la parte baja del menú de navegación izquierdo, que os mandará a una página donde se muestra el log de product-updates.log.

¿Cómo se os ha quedado el cuerpo? Os recomiendo que volváis a leer todo el tutorial otra vez para que comprendáis mejor las uniones entre archivos. Y si no os queda claro, otra, y otra vez.

Repasemos un poco lo que hemos hecho.

  • Hemos modificado el config.xml de forma que admita la redirección correcta a nuestra nueva página.
  • Hemos añadido un nuevo observador al evento ‘controller_action_layout_load_before’, que ejecuta la acción ‘showLogLink’, conectando así directamente con el Layout en ‘customer_controldeproductos_link’.
  • Hemos definido en el Layout un enlace en el menú de navegación del cliente, y el bloque que ejecutará nuestra plantilla.
  • Hemos creado la plantilla.
  • Hemos creado un controlador que se ejecuta al acceder a nuestra url correcta, y carga el layout correspondiente.

¿Lo véis mejor ahora? Espero que haya quedado más o menos claro. Si no entendéis algo, o algo no os funciona, no dudeis en comentar!

¡Un saludo!

Quizá quieras leer la primera parte: Crear una extensión para Magento.

“El reto principal de los científicos informáticos es no
confundirse con la complejidad de su propia creación”
— E. W. Dijkstra

¿Te ha gustado el artículo?
Sé el primero en calificar esta publicación.
1 Star2 Stars3 Stars4 Stars5 Stars
Loading...
Artículo escrito por

¡Exprésate! Dejanos tu comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

11 Comentarios

Johanna

Hola, necesito me pueda orientar con la creación de un widget o de que manera puedo hacer para que en mi pagina principal de tienda haya una imagen como logo para que esta me enlace a una pagina donde solo se muestren los productos con descuentos no se si me explico. ya cree la pagina pero no me aparecen los productos con descuentos si no que los productos nuevos y lo cree por medio de un widget, en una pagina cms de magento.

BrunoAkun

Hola. Muchas gracias por compartir este código, me ha sido muy útil. Bruno

Rafael Tejada

Tengo el mismo problema , me da un error en la linea 33   Fatal error: Call to a member function addHandle() on a non-object inC:xampphtdocsjmtc_trexappcodelocalCodigonexoControlDeProductosModelObserver.php on line 33

Samuel

Tengo el mismo error que Bryan Fatal error: Call to a member function addHandle() on a non-object in C:xampphtdocsmgpeappcodelocalCodigonexoControlDeProductosModelObserver.php on line 13 Si pueden ayudarnos seria genial

david

ayuda por favor.

bryan

me sale este error. Fatal error: Call to a member function addHandle() on a non-object in C:xampphtdocsjmtc_trexappcodelocalCodigonexoControlDeProductosModelObserver.php on line 33

bryan

una consulta en el TEMPLATE log.phtml C:xampphtdocsjmtc_trexappdesignfrontendbasedefaulttemplate porq no me muestra nada. y podrias explicar donde te muestra si ya esta. por favor.  

Néstor

Buen dia hermano, estoy comenzando con magento y me parece full interesante sus articulos los estoy siguiendo uno a uno, mil gracias. Hoy me he pasado revisando más de 1 hora revisando porque no me funcionaba el ejemplo y era porque le habia colocado al nombre del controlador  ControlDeProductos_LogController.php y era solo Log_controller.php, me confundi porque en el ejemplo esta de esa forma, seria bueno que lo arreglara amigo para futuras visitas, jejeje, y bueno otras personas se ahorran el ratico que me pase yo revisando porque no me funcionaba, mil gracias sigo revisando sus articulos full valiosos!!

Bruno

Hola Jose, Crees que es una buena practica crear una funcion en un controlador que cree un usuario con permisos de API automaticamente para que la extension tambien pueda ser usada externamente? Asi el usuario no tendria que hacer nada, el sistema crearia el usuario con todos los permisos de la API y podria hacerse llamadas desde el exterior. Gracias!

Jose Fernando

"Los hilos deben poderse adicionar desde el administrador en la seccion catalogo agregar productos." Me explico mejor creo que no se entiende, En el producto (Revista) debo poder adicionar los hilos para las indicaciones de la revista es decir el producto revista para hacer bufandas deberia poder adicionar uno o varios productos en este caso seria hilo y la cantidad, no es un producto dependiente, ni agrupado, el cliente puede comprar los hilos desde la pagina pero no necesariamente necesita comprar los hilos al comprar la revista

Jose Fernando

Hola Juan, muy bueno tu tutorial para hacer estas extensiones, necesito un poco de orientación para desarrollar un modulo que necesito urgente, te explico como va la cosa, en la tienda existen dos tipos de productos revistas y hilos, las revistas son productos simples y los hilos son productos configurables, lo que necesito hacer es configurar la pagina de agregar producto en el admin para que adicione lo siguiente: Tengo una revista para tejer sombreros y bufandas (Producto simple) en esta pagina se debe mostrar: El producto simple y mas abajo Sombrero : necesitas (cant) 8  (prod) hilos X Bufandas: necesitas (cant)15 (prod) hilos J Los hilos deben poderse adicionar desde el administrador en la seccion catalogo agregar productos.   De verdad necesito una orientación no estoy pidiendo codigo solo una serie de pasos para que pueda hacer eso.   sigue con el buen trabajo, saludos Jose Fernando