Archivo del Autor: Capy

Acerca de Capy

Hola me llamo Marcelo Tosco. Hace mucho tiempo que me llaman Capy y como mi apodo es muy corto y a veces ya está en uso, suelo tener que darme de alta con el apodo "capynet", aunque prefiero Capy.

En mi blog escribo de lo que yo quiera, es mi pequeño rincón de la rebeldía, aunque lo cierto es que casi siempre quiero escribir sobre informática, Drupal, Maquetacion, performance, Javascript.... Conclusión: mi blog es una mezcla de blog informático + personal, así que no se asusten si un día aparece un post que no tenga nada que ver a lo que estés acostumbrado.

Mi curriculum es mi blog, mi cuenta de Linkedin, la de Twitter y por supuesto, GitHub y Bitbucket.

Si no tenes ganas de andar escudriñando por ahí sobre mis capacidades te las resumo:
Soy un semidios en XD:
* Drupal
* PHP
* Javascript y nodejs
* CSS, SASS + Compass, LESS
* Performance a nivel de código y de servidores.
* Transmitir conocimientos.

Escribí un capitulo sobre Panels de Drupal para Forcontu.

En la vida personal soy un tipo al que le gusta andar en bici y que valora mucho la amistad.

Eso es todo. Un abrazo.

CSS & maquetación

Chrome redimensiona mas imágenes dentro de una tabla.

Me ha pasado algo curioso y solo en chrome de momento. Tengo un texto en una celda y una imagen en la otra. El problema vino cuando usé un max-width:100% para las img en general. En ese momento toda imagen que estuviera dentro de un <td> pasó a redimensionarse:

broken

Ok, Chrome también tiene sus cositas. La solución ha sido la siguiente:

/* Quiero que todas las img usen como mucho el 100% */
img {
  max-width: 100%;
}
/* Pero si la imagen está dentro de un td anulamos el max-width para evitar ese comportamiento raro. */
table tr td > img {
  max-width: none;
}

Resultado:
fixed

Y todos felices. Chau!

GIT: Mostrar gráfico de ramas en consola

GIT console graphic log

Para conseguir que la consola te muestre el gráfico e ramas (tree view en rigor) en la consola haz lo siguiente:

nano ~/.gitconfig

y al finar de lo que haya dentro del archivo pega esto:

[alias]
glog = log --all --graph --decorate --oneline

Listo, ya podés hacer

git glog

NOTA: glog = “graphic log”

Chau!

logo

Sigo acá!

Solo es que estoy ocupado (mucho mucho mucho), pero apenas tenga un hueco meto algún post que ya tengo ganas!

js-icon

Javascript: Eliminar un item de un array por su nombre

Pongan esto en su codigo:

Array.prototype.removeItem = function (a) {
    for (var i = 0; i < this.length; i++) {
      if (this[i] == a) {
        for (var i2 = i; i2 < this.length - 1; i2++) {
          this[i2] = this[i2 + 1];
        }
        this.length = this.length - 1;
        return;
      }
    }
  };

Y ya podemos eliminar elementos del array:

var frutas = ['manzana', 'banana', 'pera'];
frutas.removeItem('banana');
console.log(frutas); // Entrega ['manzana', 'pera']

Chau!

js-icon

Boilerplate (esqueleto) de plugin jQuery de la casa y en español ;)

Hola!. Me complace anunciar que pongo a disposición de todo el que quiera hacer plugins de jQuery, el boilerplate que he estado usando en los últimos años.

Es otro boilerplate como los demas, con la diferencia que al estar usandolo todo el tiempo lo fui puliendo poco a poco. Pero mucho mas importante: está en español XD

Pase pasen y vean https://github.com/capynet/jQueryPluginBoilerplate

Chau!

PHP

Detectar el navegador y toda su información desde PHP o Javascript

Hola, les hago una intro bien corta y pasamos al código.

Browscap es un proyecto que recoge la información de todos los navegadores web en una base de datos que distribuye de forma gratuita y en varios formatos.

PHP tiene soporte nativo para hacer uso de esta DB, pero debido a un par de limitaciones que PHP aun no ha solventado en su API, en GitHub un usuario creó una soluciona basada también en la DB de Browscap pero mucho mas robusta y fácil de usar.

Bien, llegados a este punto sabemos que lo que necesitamos usar es Browscap junto a la librería que se creó para explotarla.

Para mas información, toda la documentación completa de php-browscap la pueden encontrar aquí. Yo me centro en una implementación mucho mas simple porque realmente creo que de los 40 datos que entrega sobre el navegados, con apenas 7 tenemos el 99% de los casos cubiertos.

Acá tienen un ejemplo funcionando para que vean lo rápido y certero que es a la hora de conseguir la info del browser (pruébenlo con mas de uno)

Ok, pongamos algo de código que sino todo esto es muy aburrido:
Vamos a aprovechar esta librería bajo dos situaciones. en PHP y en JS

En PHP

Descarguen la librería php-browscap via Composer o a mano. Pueden saber mas sobre como descargarla aquí
Ahora que la tenemos creamos un archivo index.php para usarla.

<?php
require 'vendor/autoload.php';
use phpbrowscap\Browscap;
$bc = new Browscap('cache');
/** @var stdClass $current_browser */
$current_browser = $bc->getBrowser();
?>

Fácil, no?. Ok ya tenemos un stdClass en $current_browser con toda la información disponible del browser que llame a index.php

Aplicaciones?

Puedes por ejemplo tomar decisiones del tipo

<?php
$curr_br = $current_browser->Browser;
$CoolBrowsers = $curr_br == 'Chrome' || $curr_br == 'Firefox';
if ($CoolBrowsers) {
  add_asset('css', 'just-for-cool-browsers.css');
  $output = renderAdvancedLayout();
}
else {
  add_asset('css', 'just-for-bad-bad-browsers.css');
  $output = renderBasicLayout();
}
?>

También puedes detectar si están accediendo desde un móvil o una tablet, incluso saber si es Android, IOS, la version del SO, etc. Con toda esta información a resumidas cuentas puedes entregar un contenido muy preciso.

Beneficios

Estas entregando contenidos a medida, ergo necesitas entregar menos HTML, CSS, Js y las imágenes mas adecuadas al navegador. Esto finalmente se traduce en menos procesamiento del lado del servidor, lo que se entrega pesa menos KB y el navegador tarda menos en leer y renderizar todos los recursos (en especial JS).

En JS

Por ultimo me gustaría compartir un tip para poder aprovechar la detección de browsers en JS:
A ver, con js podemos detectar el browser usando un poco de expresiones regulares, pero llegar al detalle y la precisión a la que llega browscap es virtualmente imposible. Dicho esto, comentar que se puede entregar toda la información del browser detectado desde php simplemente haciendo esto:

<script type="application/javascript">
  var browser = <?php= json_encode($current_browser = $bc->getBrowser()); ?>;
  alert(browser.Browser);
  alert(browser.Version);
</script>

Hasta la próxima!

Desplegar una aplicación Node.js como servicio systemd (demonio)

En el mundo linux hay dos gestores de demonios que se suelen usar en casi todas las distribuciones. Upstart o systemd.

Si lo que quieres es crear un demonio para Ubuntu o cualquier otro SO que use Upstart, tienes que leer este articulo, y si lo que quieres es crear el demonio para Debian u otros que usen systemd, sigue leyendo este post.

Vamos al lio. Para nuestro demonio vamos a necesitar 3 cosas: forever, un script para crear el servicio y un script para avisar a monit para que mire nuestro servicio y lo reinicie si se cae.

El script del servicio

Como me gusta ponértelo fácil, voy a obviar la explicación y simplemente les digo que copies el siguiente código y lo pegues dentro de un archivo que se llame como el servicio que quieres crear dentro de /etc/init.d/my-service (por ejemplo).

Dentro de este archivo solo tienes que tocar dos o tres cosas al principio del archivo en la zona de configuración. Es fácil, básicamente es poner el nombre del servicio (en mi ejemplo es “my-service”), el directorio donde está alojado, y el nombre del archivo principal de la aplicación.
Hay algunas cositas mas que se pueden configurar, pero en general con esto basta.

#!/bin/bash
# This service requires you have forever app installed in your system.
### CONFIG ZONE
# This is the service name. It cant have any special char or space.
serviceName="my-service"
# Where is located your app
appFilePath="/var/node/my-service-node-app"
# Whats the name of your main app file.
appIndex="app.js"
enviroment=production
### END CONFIG ZONE
###### DO NOT EDIT BELOW THIS LINE ######
# Source function library.
. /lib/lsb/init-functions
pidFile="/var/run/$serviceName.pid"
logFile="/var/run/$serviceName.log"
command="node"
nodeApp="$appFilePath/$appIndex"
foreverApp="forever"
start() {
	echo "Starting $serviceName"
	PATH=/usr/local/bin:$PATH
	export NODE_ENV=$enviroment
	$foreverApp start --pidFile $pidFile -l $logFile -a -d -c "$command" $nodeApp
	RETVAL=$?
}
restart() {
	echo -n "Restarting $serviceName"
	$foreverApp restart $nodeApp
	RETVAL=$?
}
stop() {
	echo -n "Shutting down $serviceName"
	$foreverApp stop $nodeApp
	RETVAL=$?
}
status() {
   echo -n "Status $serviceName"
   $foreverApp list
   RETVAL=$?
}
case "$1" in
   start)
        start
        ;;
    stop)
        stop
        ;;
   status)
        status
       ;;
   restart)
   	restart
        ;;
	*)
       echo "Usage:  {start|stop|status|restart}"
       exit 1
        ;;
esac
exit $RETVAL

Tambien dejo el gist para que cualquier mejora que quieras añadir lo hagas por esta via.
https://gist.github.com/capynet/2de13de81ef8a71f2b2f

Ya tenemos servicio! ¿Y como lo usamos?. Pues como cualquier servicio:

sudo service my-service start
sudo service my-service stop
sudo service my-service restart
sudo service my-service status

Esto debería alcanzar, pero no. Este demonio no sabe volver a arrancarse si la aplicación de nodejs se para. Esa parte la vamos a solucionar usando monit.

Configurar monit

El rol de monit es el de “mirar” todo el tiempo al demonio que creamos anteriormente, y arrancarlo si este se muere.

En Debian y la mayoría de distros, a los archivos de configuración que tenemos que crear (uno por demonio) los pondremos en “/etc/monit/monitrc.d/“.
Yo por lo general creo un archivo con el formato monit-[MI-SERVICIO].conf.

Dentro de este archivo SIEMRPE vamos a usar el siguiente formato, así que simplemente cópialo, pon el nombre del demonio y el puerto, guarda los cambios, reinicia monit y listo.

check process my-service with pidfile "/var/run/my-service.pid"
        start program = "/etc/init.d/my-service start"
        stop program = "/etc/init.d/my-service stop"
        if failed
                port [THE NODEJS PORT HERE] protocol HTTP
                request / with timeout 10 seconds
        then restart

De nuevo, aqui está el gist para que contribuyas si quieres.
https://gist.github.com/capynet/c7aa09a996fe909a0960

NOTA: En algunas instalaciones de monit, hay que tocar su archivo de configuración general para que incluya los archvos de monitorización que añadamos. El archivo es /etc/monit/monitrc y tienes que editarlo como sudo y añadir al final “include/etc/monit/monitrc.d/*” si no lo tuviera ya puesto.

Bueno si a estas alturas todavía no tienes instalado forever, instalalo con sudo npm install forever -g

Hemos acabado, ya puedes arrancar monit o reiniciarlo si ya estaba corriendo. Monit va a usar el script que creamos para el para ver si el servicio está corriendo, si no es así, el solito se encarga de levantarlo y mantenerlo en funcionamiento inclusive después de reiniciar el servidor.

Chau!

CSS & maquetación

Front-end: Maquetar un buscador (input + botón) para que sea 100% fluido / responsive

La idea detrás de esto fue lograr que el buscador esté siempre al 100% del espacio que tenga disponible y no tener que preocuparme de dimensionar los input para que encajen y que el botón no caiga a dos lineas cuando se queda sin espacio.

Pueden ver como funciona si re dimensionan la ventana del navegador:

See the Pen vJBnL by Marcelo Tosco (@capynet) on CodePen.

CSS & maquetación

Front-end: Títulos multi linea con padding por cada una de las lineas

Así es como vemos un titulo cuando tiene aplicado un padding sin mas

texto-multilinea-error

Y asi es como queremos que se vea

titulo-con-padding-en-cada-linea

No voy a explicar toda la lógica que hay detrás de esto. Vayamos a la solución.

Este es el html. en div.titulo tenemos el background y en .highlight el background del texto, el padding que queremos que tenga y el hack mediante la propiedad box-shadow que es la que nos termina agregando los pedacitos de padding que nos falta entre lineas.

<div class="titulo">
    <span class="highlight">Títulos multi linea con padding por cada linea</span>
</div>
.titulo {
    padding-top: 32px;
    width: 700px;
    height: 200px;
    text-align: center;
    font-family: arial, helvetica, sans-serif;
    background: url('fondo.jpg') no-repeat 50% 50%;
}
.highlight {
    font-size: 50px;
    text-transform: uppercase;
    text-align: center;
    color: #fff;
    /*Esto es lo importante*/
    display: inline; /* Aseguramos que el elemento sea inline */
    background: black; /* Color de fondo del texto */
    line-height: 1.6em; /* Espaciado entre lineas */
    padding: 7px 0; /* padding deseado */
    box-shadow: 14px 0 0 black, -14px 0 0 black;
}

Del CSS que puse solo hagan caso a las lineas que tienen “/*Esto es lo importante*/“. El resto es decoración.

No comenté el box-shadow porque prefiero hacerlo aquí: La magia se da en box-shadow. Solo tienes que tocar dos parámetros. El color cámbialo de black al que hayas puesto en la propiedad background, y los valores 14px y -14px ajustalos para arriba o para abajo hasta que te guste el padding lateral que hay en cada una de las lineas.

Listo!

Artículo original: css-tricks.com