Cuando has valorado bien un proyecto, y es tal el nivel de personalización que se quiere alcanzar, no queda más remedio que hacer un desarrollo artesanal, o a la larga te arrepentirás. Ya que partir de un CMS prefabricado es, a veces, más que una ayuda un lastre. Cuando quieres la máxima flexibilidad, velocidad en las modificaciones.. y por supuesto, la máxima calidad.. tienes que ir al desarrollo sobre frameworks. Ya hablé sobre esto en otro post anterior..
Hoy vengo a empezar con una serie de plugins o bundles para Symfony, hoy con uno para programar tareas. Ya sea para enviar emails transaccionales, para programar tareas de marketing, crawleos de sitios web, generar sitemaps, o lo que sea que quieras automatizar.. Aquí verás como en un rato tienes montado un estupendo programador de tareas.
Con este programador de tareas ya tienes el panel de control hecho. Es decir, te evitas la construcción del panel, y podrás ir al siguiente paso en menos de una hora. Que será directamente el ir a crear las tareas tal y como las necesites para tu proyecto 🙂
Puede ser que necesitemos en Magento alguna forma de almacenar datos globales, es decir, que no son relacionados con ningún otro elemento individual.
Todo o casi todo en Magento tiene atributos: los productos, clientes, pedidos, direcciones, facturas, abonos, etc.. Pero para almacenar estos atributos globales tenemos dos opciones, o los guardamos como variables de configuración o como variables del core de Magento.
La diferencia es que las variables de configuración se cachean y las del core no. Muchas de las variables de configuración se pueden gestionar desde el panel de control en Sistema > Configuración. Si modificamos mediante código las variables de configuración no se refrescarán los datos, sin embargo si modificamos las variables mediante el panel de control casi todas se refrescan en el momento. Sin embargo con las variables del core esto no pasa.. conforme se guardan se tienen actualizadas al consultarlas de nuevo. Usar variables del core provoca más consultas a la base de datos, sin embargo, las variables de configuración se actualizan sólo cuando se refresca la caché de variables de configuración.
El contenido es el rey para el posicionamiento, rezan muchos SEOs y muchas herramientas para SEOs. He leído por Internet que muchos hablan de que lo más importante para posicionar las páginas web es que el contenido sea bueno, que sea geniuno, interesante para el usuario.
Desde nuestro punto de vista, tenemos varios enfoques para hacernos una idea de si el contenido de una web es bueno. El más sencillo es la tasa que hay entre el texto y el código HTML, CSS y Javascript de nuestra web. Realmente, es la tasa entre el texto y el HTML, CSS y Javascript, aunque muchos se olvidan de que no sólo hay HTML.. Y muchas veces este CSS y Javascript puede ser tanto que la tasa de texto resultante baje demasiado. Todo esto se reduce en la tasa llamada Text to HTML ratio.
Hoy vengo a compartir otro pequeño script para testear el tiempo de respuesta de un servidor. Este es el llamado TTFB, Time To First Byte en inglés. Simplemente es el tiempo que pasa entre que tu navegador pide una web hasta que empieza el servidor a enviar los bytes de respuesta. Esta prueba nos da una buena visión de si el servidor y la web se pueden optimizar. Un TTFB bajo es buena señal, indica que tanto el servidor (a nivel hardware y software) como la aplicación web esta todo bien optimizado. Sino, ya tenemos algo en lo que enfocarnos.
Es el gran dilema en el desarrollo de aplicaciones web. Te hablan sobre un proyecto; con unos requerimientos, unas especificaciones. Debes elegir con las premisas que te dan: presupuesto, tiempo de entrega, calidad, flexibilidad, mantenibilidad, practicidad.. ¿Existe ya una solución para el proyecto? ¿Se puede partir de un CMS y modificarlo? ¿Son demasiadas las modificaciones que se van a hacer al CMS? ¿Es viable partir de un framework de calidad? ¿Buscamos máxima calidad, o menor precio? ¿Hay muchos desarrolladores disponibles en el mercado para mantener el proyecto?
He recibido una consulta sobre cómo sacar el ciclo de ventas de Magento. Ya respondí, pero los cálculos no me salen exactos. Así que jugando, jugando.. he tratado de encontrar cómo Magento calcula el ciclo de ventas que vemos en el panel de control.
Como no me daba exacto, he recorrido después las facturas, que tampoco me daba exacto. Y después añadí el recorrido de los abonos. Con y sin impuestos, tampoco me daba la misma cifra. Balanceando facturas con abonos, con y sin impuestos, que es lo correctamente contable tampoco me salía la misma cifra, aunque se iba acercando.. Conclusión, que en una tarde recorriendo los pedidos, facturas y abonos, no salen los mismos cálculos que te muestra Magento en el panel de control. Pero aquí dejo la información para el que le pueda servir 😉 de todas formas, contablemente, lo correcto son contabilizar las facturas y abonos.
Una cosa que puede ser útil para un Prestashop es ponerlo en modo catálogo. Cuando hacemos esto, Prestashop se limitará a sólo mostrar los productos que tengamos visibles. Además se deshabilitarán todas las funcionalidades de una tienda online. Es decir, que no se podrá añadir productos al carro ni hacer la compra.
Sin embargo, se podrá seguir trabajando en el panel de control todo lo que necesitemo. Además, en el front, los visitantes seguirán pudiendo visitar los productos, buscarlos, ver las fichas detalladas, navegar por las categorías.. Así que si no queremos poner a la venta productos lo que tenemos que hacer es poner Prestashop en modo catálogo.
Cómo
En el panel de contrl entramos en Preferencias > Productos activamos el modo catálogo como se muestra en la imagen siguiente y le damos a guardar:
Es ingente la cantidad de cosas que se pueden hacer en un Magento recién instalado. Es un CMS orientado al eCommerce muy completo. También muy orientado a la optimización para motores de búsqueda (SEO). Tiene muchas características que le dotan de gran flexibilidad. Entre ellas es la «sencilla» forma de ampliar funcionalidades sin que nada se rompa. Siempre claro, que hagamos lo que en programación se llama overriding. De esta forma, no tocaremos los ficheros originales, ampliando o modificando su funcionamiento en otro espacio de trabajo.
Qué es hacer overriding
Es la forma correcta de hacer las cosas. Si queremos modificar o ampliar funcionalidades de un CMS, lo que siempre debemos de hacer es overriding. Por ejemplo, en WordPress es bastante habitual encontrarte con plantillas que se han modificado. Si se han modificado con el editor que te trae WordPress en el mismo panel de control, sin antes haber hecho una plantilla hija de la original, el problema es que esto no es hacer overriding. Y cuando vamos a actualizar la plantilla.. ¡zasca! se borran todos los cambios hechos.
Las nubes por definición son sistemas informáticos que crecen o decrecen según la necesidad. Son conjuntos de servidores/servicios que se adaptan a la demanda. Con todo esto, llegamos a una de las cosas más interesantes de AWS, el auto-escalado o la tolerancia a fallos, además de la personalización de los servidores. Podemos controlar la carga de los servidores que haya. Además automatizar el arranque y parada a ciertas horas de algunos de los servidores. O podemos duplicar los sistemas para evitar los ‘single point of failure como una casa’.
En OpsWorks tenemos herramientas muy interesantes relacionadas con esto. Algo rústicas, quizá clásicas dirían algunos. Pero gracias a ello, sin límites en la flexibilidad para configurar. Y si lo llevamos al extremo, este mismo sistema nos puede servir para automatizar la creación de nuestros servidores con herramientas como Chef y Kitchen. Todo esto y mucho más es lo que se puede hacer con el clásico OpsWorks.
Primero tendremos que ver qué son las AMIs. Cómo crear una manualmente o automáticamente. Y finalmente veremos cómo se usan, para hacernos una buena idea de qué podemos hacer en OpsWorks, y si es o no lo que necesitamos. Quizá es interesante ir a Docker con el EC2 Container Service o a CloudFormation, pero esto son otros temas..
No voy a entrar al detalle de cómo hacer cada cosa, no terminaría nunca. Así que si buscas una guía general para enfrentar después cada detalle poco a poco, este es tu post.
¡Hola de nuevo! Continuando con el post anterior sobre el desarrollo de temas para WordPress. Inevitablemente, ya sea más tarde o más temprano, llegaremos a querer desligarnos totalmente de modificar los temas de otros. Todos hemos empezado haciendo pequeños arreglos con el editor que tiene WordPress. Si has seguido el post anterior sobre cómo hacer un theme hijo de otro te habrás quedado con ganas de más, así que continuándolo vamos a crear uno básico 100% tuyo para lo que necesites.
Ahora bien, lo normal es que si estás aquí alguna vez hayas jugueteado con temas de WordPress de otros, modificándolos y llegando a un punto en el que no puedes actualizarlo porque perderías las modificaciones. Por otro lado si haces un tema hijo siempre vas a depender del padre, y también puede que haya actualizaciones del padre que rompan tu diseño. Así que la forma más profesional de solucionar esto es hacer tu propio tema, 100% tuyo, y totalmente desligado de cualquier otro.
Una de las bondades que tienen Magento es su flexibilidad. En este post vamos a ver el tema de los atributos de producto, cual es su scope o alcance. En general, esto se facilita mucho con su uso interno del modelo de datos EAV. Gracias a EAV que podemos gestionar muchos valores de atributos de cada elemento sin tener que modificar la base de datos. Es decir, no tenemos que hacer una columna nueva para cada atributo nuevo. Sino que se da de alta el atributo en una tabla, y en otra se guardan los valores de los atributos sin haber hecho absolutamente ninguna modificación en la estructura de la base de datos.
Disponemos de tres niveles de configuración normalmente, aunque realmente hay cuatro, para configurar muchas de las cosas que hay dentro de un Magento. Tenemos el nivel de website, de store y de store view. Traducidos son sitio web, tienda, y vista de tienda; y además tenemos el nivel global. Por ejemplo, si vamos a las configuraciones de tiendas podemos tener varios nombres de dominio (uno por website), cada uno con sus configuraciones, plantillas distintas, productos distintos, incluso clientes distintos asignados a cada website o compartidos entre todos los websites. Dentro de un website podemos tener varias tiendas o stores. Y de cada tienda podemos tener varias vistas de tienda, incluso pudiendo cambiar las plantillas o muchas de sus configuraciones de productos, categorías, etc..
El caso de los productos
Volviendo a los productos, primero tenemos que los podemos asignar a cada website. Es decir, un producto puede publicarse en uno de los websites mientras que en otro no. Si vamos al listado de productos nos encontramos en un Magento 1.9 arriba con un desplegable como el de la imagen de al lado, donde podemos configurar los productos a nivel de store view.
Los productos se trabajan al más bajo nivel, al de store view. Esto es así porque el nivel de store view se suele usar para traducir la web. Es decir, publicamos un producto en un website, y configuramos a nivel de vista de tienda cómo lo va a ver el usuario. Si tenemos una vista de tienda por cada idioma, podremos configurar su nombre, descripción, características, etc.. traduciéndolas para cada idioma.
El nivel de los atributos de producto
Podemos dar de alta y configurar nuevos atributos, en la zona de gestión de atributos. Un listado de atributos de ejemplo podría ser tal que así:
Si el valor del atributo es el mismo en todas las tiendas o vistas de tienda, entonces debería de ser global. Si el valor es distinto, traducible para cada store view, debe de tener el nivel de store view. Es importante saber que todas las etiquetas que se muestran siempre se pueden traducir para cada store view, independientemente de los valores que tome dichos atributos. Es decir, no confundamos las etiquetas que podemos traducirlas con los valores que también podemos traducirlos, no te lleve a confusión.
El atributo de producto ‘status’ es de sistema
Todos los atributos del listado anterior no son de sistema, con lo que no tienen limitación para configurarlos como queramos. Pero los de sistema sí que están limitados. Para este post vamos a trabajar con un atributo que ya viene configurado en Magento que es el estado (status). El estado puede estar habilitado o deshabilitado, y viene configurado a nivel de sitio web. Este atributo puede configurarse para que esté a nivel de website o nivel global. Si lo tenemos a nivel de website entonces podremos habilitar o deshabilitar un producto independientemente en cada website de nuestro Magento.
Esta flexibilidad está bien, pero sólo en ciertos casos. Si tenemos varios websites, de cada uno por lo menos una store, y dentro de cada store podemos tener varias store views para traducir las tiendas.. se puede reducir la cantidad de configuraciones si ponemos el nivel adecuado para cada atributo. Volviendo al caso del atributo status, si me interesa que cuando deshabilite un producto lo haga para todos los websites, entonces debemos de tenerlo a nivel global. De lo contrario, si tenemos 3 sitios web, para estar seguros de que deshabilitamos o habilitamos correctamente el productos en todos los websites deberemos de entrar en la configuración de producto varias veces y comprobarlo.
Así que vamos a ponerlo a nivel global y asegurarnos de que no quedan valores personalizados a nivel de website. Y en tal caso los borramos. Así evitaremos esta excesiva navegación por las fichas de producto. Y así nos aseguramos de que un producto deshabilitado, lo está realmente en todos los websites.
Finalmente, pasando a global el atributo status
Entramos en la configuración del atributo y lo modificamos para que sea global:
Sólo nos falta entrar a la base de datos y, en este caso, borrar todas las configuraciones del atributo a nivel de website que se hayan hecho para que sólo se aplique la configuración global en cada producto. Si se nos quedara en la base de datos algún valor personalizado sin borrar, Magento cogería dicho valor personalizado, en caso de no encontrar valores personalizados de nivel más bajo entonces cogería el valor global.
Encontrando el identificador del atributo
Para esto no tenemos más que entrar a la base de datos e ir a la tabla eav_attribute. Aquí tenemos definidos los atributos que gestionamos en el panel de control. De forma que, tenemos dos columnas con las que identificamos el atributo status: la columna attribute_code, y la columna attribute_id. Aquí buscamos el código que le hemos puesto al atributo, en este caso ‘status’, que no lo hemos creado nosotros porque es de sistema y ya viene configurado.
Ya hemos encontrado el identificador del atributo, que es el 96. Ahora ya podemos ir a revisar los valores que ha ido tomando el atributo para las distintas vistas de tienda. Para esto vamos a la tabla catalog_product_entity_int que es donde se guardan los ‘valores enteros de los atributos de entidades de productos’ como su nombre indica en inglés.
Como podemos ver en la imagen, el atributo 96 está cogiendo los valores 1, 2.. para el status el valor 1 es de producto habilitado, el 2 es deshabilitado. Según vemos en la imagen y haciendo un par de consultas podemos ver que la store_id es cero siempre en mi caso. A saber, la store_id cero es el valor del atributo global, es el que coge Magento en caso de encontrar ninguno personalizado. Si tenemos guardados valores distintos para las vistas de tienda, entonces habrían valores con store_id distintos, donde cada store_id corresponde con el identificador de la store.
Cómo listar los stores de una tienda lo cité en el post este, en donde se listan primero los store_id para luego ir recorriendo los productos y asignándolos a todas las stores. Podemos coger aquel script y listar los store_id y así poder editar o simplemente borrar las configuraciones de algunas de las stores.
Borrando valores de atributo personalizados
En este caso, si quisiéramos borrar todas los valores de status personalizados en cada store view bastaría con ejecutar la consulta siguiente y vemos si hay dichos valores personalizados:
SELECT * FROM magento_maxmovil.catalog_product_entity_int
WHERE attribute_id = 96 AND store_id != 0;
Si los hay simplemente modificamos la anterior consulta para borrarlos:
DELETE FROM magento_maxmovil.catalog_product_entity_int
WHERE attribute_id = 96 AND store_id != 0;
Con esto ya nos aseguramos que no vaya a haber problema y hemos pasado el atributo status a scope global. Esto mismo se puede hacer para cualquier otro atributo.
Con esto queda terminado 🙂 otro día más 😉 Un saludo!
Este estupendo CMS orientado a la venta online de productos hace las delicias de los vendedores, de igual modo de los maquetadores, y cómo no, también de los programadores.
Como analista programador llevaba ya un tiempo queriendo meterle mano a las entrañas de Magento. Así que poco a poco, he ido cogiendo los manuales para el usuario, luego el del diseñador, y ahora tengo entre manos el del programador. Ahora según van surgiendo las necesidades voy haciendo incursiones cada vez más a fondo en el código fuente de esta humongous web application.
La verdad es que lo estoy disfrutando porque Magento está desarrollado con una buena estructura y sobre un gran framework de desarrollo PHP, el Zend Framework. Incorporando técnicas de programación que le dan una gran flexibilidad sin añadir demasiada complejidad.