En la siguiente entrada vamos a explicar como modificar una carga CMS. El formulario simulará estar en una página estática o de contenido CMS pero no es así, la página que definamos tendrá su propia tpl.
Índice
Empecemos…
Vamos a dar el caso de que hemos creado una página CMS de contenido estático en Prestashop, esta a su vez tiene un formulario que realiza la acción de recoger preferencias de un cliente.
El formulario nos va a servir para solicitar piezas antiguas a un comercio dedicado a esto mismo, las antigüedades.
Entonces el formulario apuntará en su action a algo como {$urls.base_url}es/content/11-solicita-tu-pieza
Visualmente dispondremos de algo como esto:
Una vez completado y validado el formulario, si todo ha sido correcto mostraremos un mensaje de OK. Pero en caso de que no haya sido así, mantendremos los datos del formulario e indicaremos el error y es por eso que debemos trabajar con variables smarty no soportadas en los contenidos CMS.
Filtrando páginas CMS en page.tpl
Primero accedemos al panel de administración donde tenemos creada nuestra página estática y recuperamos el id. Como hemos visto en el enlace anterior colocado en el formulario, el id con el que vamos a trabajar es el 11.
Ahora abrimos el script que tenemos en tu-ecommerce/themes/TheStyle/templates/cms/page.tpl y le indicamos que en caso de ser el CMS con id 11 cargue de otro modo. Es aquí donde vamos a modificar una carga CMS.
<!-- Si se trata de la página de "solicita tu pieza" carga su propia template --> {if $cms.id == 11} {include file="catalog/_partials/miniatures/solicita-tu-pieza.tpl" cms=$cms} {else} {block name='cms_content'} {$cms.content nofilter} {/block} {block name='hook_cms_dispute_information'} {hook h='displayCMSDisputeInformation'} {/block} {block name='hook_cms_print_button'} {hook h='displayCMSPrintButton'} {/block} {/if}
Vamos a la ruta donde hemos indicado que tenemos la tpl y pegamos el contenido del form, para los más cómodos os paso el trozo de código 🙂
<form id="solicitatupieza" name="solicitatupieza" action="{$urls.base_url}es/content/11-solicita-tu-pieza" method="post" enctype="multipart/form-data"> <!-- Creo capa para aplicar border y margenes --> <div style="border: 1px solid #ededed; margin-bottom: 20px;"> <!-- Bootstrap siempre se inicializa con la clase ROW --> <div class="row"> <div class="col-md-12"> <div style="margin-right: 0px; margin-left: 0px;"> <h4 class="contacto-titulo color-corportivo degradado">SOLICITA TU PIEZA</h4> </div> </div> </div> <div class="row" style="margin-top: 20px; margin-bottom: 20px;"> <!-- Bootstrap dispone de 12 columnas, por lo tanto si definimos col-md-6 estamos partiendo la pantalla en 2 columnas de 6 --> <div class="col-md-7" style="padding-left: 30px; padding-right: 30px;"><img src="{$urls.base_url}img/cms/solicita-tu-pieza/solicita-tu-pieza-02.jpg" alt="Nosotros" width="100%" /></div> <div class="col-md-5" style="padding-left: 30px; padding-right: 30px;"> <div class="row cajas-bajas-y-tasaciones"> <div class="col-md-12"> <div><label class="form-control-label">Nombre (*)</label></div> {if isset($datos['name']) && $datos['name'] != ''} {assign var="nombre" value=$datos['name']} {else} {assign var="nombre" value=""} {/if} <div class="form-group"><input class="form-control" name="name" id="name" type="text" maxlength="50" value="{$nombre}" placeholder="Campo obligatorio…" /></div> </div> </div> <div class="row cajas-bajas-y-tasaciones"> <div class="col-md-12"> <div><label class="form-control-label">Correo electrónico (*)</label></div> {if isset($datos['email']) && $datos['email'] != ''} {assign var="email" value=$datos['email']} {else} {assign var="email" value=""} {/if} <div class="form-group"><input class="form-control" name="email" id="email" type="text" maxlength="50" value="{$email}" placeholder="Campo obligatorio…" /></div> </div> </div> <div class="row cajas-bajas-y-tasaciones"> <div class="col-md-12"> <div><label class="form-control-label">Teléfono</label></div> {if isset($datos['telefono']) && $datos['telefono'] != ''} {assign var="telefono" value=$datos['telefono']} {else} {assign var="telefono" value=""} {/if} <div class="form-group"><input class="form-control" name="telefono" id="telefono" type="text" maxlength="11" value="{$telefono}" /></div> </div> </div> <div class="row cajas-bajas-y-tasaciones"> <div class="col-md-12"> <div><label class="form-control-label">Descripción de la pieza (*)</label></div> {if isset($datos['message']) && $datos['message'] != ''} {assign var="message" value=$datos['message']} {else} {assign var="message" value=""} {/if} <textarea class="form-control" name="message" rows="3" cols="22" placeholder="Campo obligatorio…">{$message}</textarea></div> </div> <div style="margin-top: 20px; margin-bottom: 20px;"> <div class="row cajas-bajas-y-tasaciones"> <div class="col-md-3"></div> <div class="col-md-6"><input class="btn btn-primary" type="submit" name="submitMessage" value="ENVIAR" /></div> <div class="col-md-3"></div> </div> </div> </div> </div> </div> <div style="border: 1px solid #ededed;"> <div class="row"> <div class="col-md-12"> <div style="margin-right: 0px; margin-left: 0px;"></div> </div> </div> </div> </form>
¿Por qué asignamos un contenido fijo en vez de hacerlo desde el gestor de CMS?
Como he comentado brevemente más arriba, porque en este caso vamos a tener valores smarty en nuestra vista que el gestor de contenidos CMS al guardar no sabe interpretar.
Imaginemos que queremos tras darle al botón submit y devolver un error mantener el contenido de las cajas para que el cliente no tenga que escribir los datos de nuevo. Pues para ello necesitamos hacer esto o crear un controlador propio para esta acción.
En una próxima entrada veremos como crear un nuevo controller junto a su vista en prestashop 1.7.
Modificando el controlador CmsController.php
Vamos a modificar este controller para que dependiendo de la página CMS realice unas acciones u otras. Su ruta es la siguiente: tu-ecommerce/controllers/front/CmsController.php
En la función initContent() añadimos este trozo de código:
// Página de solicita tu pieza: tu-ecommerce/tu-idioma/content/11-solicita-tu-pieza if($this->cms->id == 11 && isset($_POST['submitMessage']) ){ $this->envioSolicitaTuPieza($_POST); // Asignamos mensaje de confirmación. $this->context->smarty->assign([ 'datos' => $_POST ]); }
Y en esta misma función en la línea donde dice $this->setTemplate debe quedar de este modo:
$this->setTemplate( 'cms/page', array( 'entity' => 'cms', 'id' => $this->cms->id, 'datos' => $_POST) );
Terminamos creando el método envioSolicitaTuPieza() este queda como muestro:
public function envioSolicitaTuPieza($datos) { $message = Tools::getValue('message'); if (!($from = trim(Tools::getValue('email'))) || !Validate::isEmail($from)) { $this->context->controller->errors[] = $this->trans('Invalid email address.', array(), 'Shop.Notifications.Error'); } elseif (!Validate::isCleanHtml($message)) { $this->context->controller->errors[] = $this->trans('Invalid message', array(), 'Shop.Notifications.Error'); } elseif (!$datos['name']) { $this->context->controller->errors[] = $this->trans('El campo nombre no puede estar vacío.', array(), 'Shop.Notifications.Error'); } elseif (!$datos['message']) { $this->context->controller->errors[] = $this->trans('El campo mensaje no puede estar vacío.', array(), 'Shop.Notifications.Error'); } else{ // Aplicamos la conversión de variables. $var_list['{name}'] = $datos['name']; $var_list['{telefono}'] = $datos['telefono']; $var_list['{email}'] = $datos['email']; $var_list['{message}'] = $datos['message']; // Destruimos valores para que el formulario aparezca limpio if (!count($this->context->controller->errors)) { $this->context->smarty->assign([ 'datos' => '' ]); $this->context->controller->success[] = $this->trans('Your message has been successfully sent to our team.', array(), 'Modules.Contactform.Shop'); } } }
Aquí lo que hacemos es muy intuitivo, validamos los campos que hemos definido como obligatorios y dependiendo del resultado lanzamos un mensaje u otro.
El resultado final tras lanzar un error sería algo como esto:
Y poco más que comentar, espero que os haya sido de mucha utilidad la entrada de hoy. Cualquier duda ya sabes… comenta y te atenderé lo antes posible.
Versiones utilizadas, tiempo y dificultad de desarrollo:
Dificultad del ejercicio: Experto.
Tiempo de realización: 30 minutos.
Plataforma: Prestashop 1.7.1.2
Gran publicación, falto incautación, quería saber si podrías escribir un poco más sobre este tema.
Estaría excesivo complacido si pudieras proyectar un exiguo más.
¡Salud!
Hola, ¿realmente hacía dónde necesitas que enfoque la ampliación de este artículo?
Dime qué necesitas exactamente e intentaré ayudarte.
Saludos.
Luis, me ha parecido muy interesante.
Podrías implementar la plantilla html de mail que envía con la recogida de datos.
Gracias.
a que dirección envia el mail?
hay plantilla html o txt para es mail?
gracias