Escael Marrero https://www.escael.com Front-end Development Fri, 12 May 2023 21:51:14 +0000 es hourly 1 https://wordpress.org/?v=6.7.2 Subdominio Blogger en Cloudflare https://www.escael.com/subdominio-blogger-en-cloudflare/ Tue, 26 Apr 2016 08:05:37 +0000 http://www.escael.com/?p=591 Esta entrada será muy sencilla. Una breve explicación de como configurar un subdominio que responde a un sitio en Blogger y que esta gestionado con Cloudflare. Mi dominio principal es escael.com y como soy aficionado a la fotografía tengo un blog con la url escael.blogspot.com que decidí redireccionar a un subdominio de escael.com, fotos.escael.com. Hasta […]

The post Subdominio Blogger en Cloudflare first appeared on Escael Marrero.]]>
Esta entrada será muy sencilla. Una breve explicación de como configurar un subdominio que responde a un sitio en Blogger y que esta gestionado con Cloudflare.

Mi dominio principal es escael.com y como soy aficionado a la fotografía tengo un blog con la url escael.blogspot.com que decidí redireccionar a un subdominio de escael.com, fotos.escael.com.

Hasta aquí la documentación de google es muy clara y no voy a explicar aquí. Para configurar los DNS con Cloudflare debe quedar de la siguiente forma:

Blogger y Cloudflare

Lo importante es desmarcar la opción de Cloudflare de proxy HTTP y dejar solo gestión de DNS.

Espero que le sirva a alguien, yo pase varias horas y no encontraba como solucionarlo.

The post Subdominio Blogger en Cloudflare first appeared on Escael Marrero.]]>
Instalar servidor NFS https://www.escael.com/instalar-servidor-nfs/ Fri, 10 Jul 2015 11:03:31 +0000 http://www.escael.com/?p=579 Voy a preparar otra chuleta, de esas que ya van siendo comunes por aquí, que me ayudan a tener recogido y organizado, de cierta manera, las informaciones que necesito para el día a día. Hoy voy a explicar de manera rápida y sencilla como instalar un servidor NFS para comunicarnos entre el mac y la […]

The post Instalar servidor NFS first appeared on Escael Marrero.]]>

Voy a preparar otra chuleta, de esas que ya van siendo comunes por aquí, que me ayudan a tener recogido y organizado, de cierta manera, las informaciones que necesito para el día a día.

Hoy voy a explicar de manera rápida y sencilla como instalar un servidor NFS para comunicarnos entre el mac y la máquina virtual que tengamos instalada. Hasta ahora he utilizado Samba, pero este protocolo de red es muy lento y en ocasiones me crea «bloqueos» con el IDE (Sublime Text) y manda todo a la mier….

Pues investigando un poco, veo que NFS es mucho mejor, al menos más rápido (esto lo he podido comprobar). Pero que es NFS. Hurgando por ahí me encontré con esto:

«NFS (sistema de archivos de red: «Network File System») es un protocolo que permite acceso remoto a un sistema de archivos a través de la red. Todos los sistemas Unix pueden trabajar con este protocolo; cuando se involucran sistemas Windows, debe utilizar Samba en su lugar».

Pongamos manos a la obra:

1. Instalar servidor NFS. En nuestra máquina virtual, en mi caso, Ubuntu Server 14.04.2 LTS:

sudo apt-get install nfs-kernel-server nfs-common rpcbind

2. Comprobar la instalación:

grep nfs4 /proc/filesystems

que debe devolver algo como esto:

NFS

3. Ver cual es nuestro user ID y grupo ID para posteriormente incluirlos:

echo $UID
echo $GROUPS

4. Editar el fichero /etc/exports

sudo vi /etc/exports

5. Agregar la siguiente configuración:

/var/www/html ip-del-cliente(rw,async,insecure,all_squash,anonuid=1000,anongid=1000)

en anonuid=1000,anongid=1000 agregar el id del usuario y del grupo respectivamente que hemos obtenido en el punto 3. Esto permite tener permisos de escritura.

6. Reiniciar el servidor de NFS:

sudo /etc/init.d/nfs-kernel-server restart

7. Montar el directorio en nuestro Mac:

mount -t nfs ip-del-servidor:/var/www/html /Users/usuario/carpeta-del-proyecto/

8. Desmontar el directorio en nuestro Mac:

umount /Users/usuario/carpeta-del-proyecto/

Y eso sería todo. El directorio montado aparecerá en la carpeta que hayamos seleccionado.

The post Instalar servidor NFS first appeared on Escael Marrero.]]>
Automatizar tareas frontend https://www.escael.com/automatizar-tareas-frontend/ Fri, 19 Jun 2015 08:48:05 +0000 http://www.escael.com/?p=568 Automatizar tareas de frontend es uno de los procesos que se han ido imponiendo en la actualidad en todo desarrollo web. El mismo posibilita que se gestionen procesos tan diversos como compilado de Sass o Less, minificación y concatenación de CSS y JS, comprimir imágenes, verificar errores y multitud de tareas más. Desde que comencé […]

The post Automatizar tareas frontend first appeared on Escael Marrero.]]>
Automatizar tareas de frontend es uno de los procesos que se han ido imponiendo en la actualidad en todo desarrollo web. El mismo posibilita que se gestionen procesos tan diversos como compilado de Sass o Less, minificación y concatenación de CSS y JS, comprimir imágenes, verificar errores y multitud de tareas más. Desde que comencé a investigar este apartado del desarrollo web no concibo comenzar un proyecto que no sea siguiendo estos pasos.

Existe multitud de documentación al respecto, en este post he querido resumir los pasos que sigo normalmente. Aprovecho que tengo que instalar una máquina virtual nueva y relato lo que voy haciendo y así me sirve de guía para futuros proyectos y a vosotros os puede servir. Porque si habéis indagado un poco sobre el tema, cada quien hace esto como le viene en gana y la documentación cambia de un sitio a otro. Resumiendo pongo la que a mi me ha funcionado, para sumar un poco de caos a este mundo de muy señor mio, como dicen por ahí.

Nota: Esta documentación esta orientada a Ubuntu. Aunque es perfectamente aplicable a cualquier sistema.

1- Sino lo tienes ya, instala Git como controlador de versiones:

Ahora vamos a instalar Gulpjs para gestionar las tareas de nuestro despliegue de estáticos. Pero antes necesitamos npm como paquete de NodeJs, y tener instalado NodeJs:

  • sudo apt-get update
  • sudo apt-get install nodejs

Hasta aquí tenemos instalado NodeJs. Ahora instalamos npm:

  • sudo apt-get install npm

A continuación viene un proceso que no acabo de entender bien  pero que consiste en dar permisos al usuario para que pueda instalar y ejecutar npm sin ser root (los paquetes de NodeJs se instalan a nivel global o a nivel local). De no ser así tendríamos que instalar todos los paquetes de npm como root y esto no esta recomendado, además de ser un coñazo el ir introduciendo contraseña cada vez que queramos hacer algo. Por lo tanto, poner como propietario al usuario a todas los paquetes de npm.

  • sudo chown -R nombredeusuario ~/.npm
  • sudo chown -R nombredeusuario /usr/local/lib/node_modules

Esta línea no la tengo muy clara, pero basicamente ejecuta npm a nivel local:

  • npm config set prefix ‘~/.npm-packages’

Ahora, si he entendido bien, esta configuración vuelve a su punto de origen una vez que se reinicia la sección de usuario. Sería molesto tener que correr dicho comando cada vez que iniciemos la sección. Para ello editamos el fichero .bashrc y agregamos lo siguiente:

  • export PATH=»$PATH:$HOME/.npm-packages/bin»

Por último creamos un enlace simbólico de NodeJs a node:

  • ln -s /usr/bin/nodejs /usr/local/bin/node

(Ayuda en NPM sobre permisos: Fixing npm permissions)

En Digital Ocean tienen un tutorial bastante completo sobre el tema.

Otra de las aplicaciones que vamos a utilizar es Bower, que nos permitirá gestionar los paquetes y sus versiones. Para instalarlo seguimos con npm:

  • npm install -g bower

Una vez hecho podremos instalar Gulp a nivel global. Fijarse que no usamos sudo:

  • npm install –global gulp

Verificamos que Gulp.js ha sido instalado correctamente.

  • gulp -v

Si esta correcto saldrá algo así:

  • CLI version 3.9.0

Ahora vamos a instalar Gulp en un proyecto local. Creamos una carpeta que será la que contendrá nuestro proyecto. Dentro de la misma creamos un fichero:

  • gulpfile.js

A continuación tecleamos la instrucción:

  • npm init

que nos pedirá los datos de nuestro proyecto y lo vamos rellenando según nuestra información.

Para instalar gulp en el proyecto local:

  • npm install –save-dev gulp

Aquí ya estaríamos listos para instalar los paquetes de gulp que vamos a utilizar. Voy a documentar las de uso común y pondré el fichero gulpfile.js con ejemplos de su implementación. Los mismos se pueden hallar aquí: https://www.npmjs.com/package/package

Estos son los que vamos a instalar:

Todos estos paquetes se instalarán en local. Las instrucciones son las mismas, solo cambia el nombre:

  • npm install gulp-sass –save-dev
  • npm install gulp-concat –save-dev
  • npm install –save-dev gulp-uglify

Cuando hayamos instalado estos paquetes ya podemos abrir el gulfile.js y crear nuestras primeras tareas:

var gulp 		= require('gulp');
var sass 		= require('gulp-sass');
var concat 		= require('gulp-concat');
var uglify 		= require('gulp-uglify');

gulp.task('sass', function () {
	gulp.src('sass/**/*.{scss,sass}')
	.pipe(sass({
		errLogToConsole: true
	}))
	.pipe(gulp.dest('css'));
});

gulp.task('watch', function() {
	gulp.watch('sass/**/*.{scss,sass}', ['sass'])
});

gulp.task('default', ['sass', 'watch']);

Como podemos observar la configuración de tareas es muy sencilla. Primero incluimos los paquetes que vamos a necesitar. Después creamos la tarea con gulp.task y al final la lanzamos con el comando gulp en terminal. sino le pasamos ningún parámetro el va a llamar a la task «default».

Y eso sería todo. Espero que este mini tutorial os pueda servir para algo. Por mi parte ya tengo todos los pasos que necesito en un solo lugar 🙂 Si veo que falta algo útil lo iré incluyendo, o si alguno por ahí necesita que amplíe no dudéis en dejar un comentario.

The post Automatizar tareas frontend first appeared on Escael Marrero.]]>
Enviar emails con Laravel https://www.escael.com/enviar-emails-con-laravel/ Tue, 04 Nov 2014 00:27:59 +0000 http://www.escael.com/?p=539 Me he propuesto aprender un framework de PHP. El objetivo realizar algunos de los proyectos que tengo en mente, ya que wordpress en ocasiones se me queda pequeño. He intentado utilizar OctoberCms, que aunque no es un framework, esta basado en uno muy de moda y al parecer de fácil uso: Laravel. Desafortunadamente he chocado […]

The post Enviar emails con Laravel first appeared on Escael Marrero.]]>
Me he propuesto aprender un framework de PHP. El objetivo realizar algunos de los proyectos que tengo en mente, ya que wordpress en ocasiones se me queda pequeño. He intentado utilizar OctoberCms, que aunque no es un framework, esta basado en uno muy de moda y al parecer de fácil uso: Laravel. Desafortunadamente he chocado contra un muro de ignorancia por mi parte. El desconocimiento de conceptos avanzados de programación orientada a objetos y la poca documentación para dummies existente sobre OctoberCms, me ha conducido a dejar, por el momento, esta fantástica herramienta para crear sitios y volcarme al estudio de Laravel, que si cuenta con montones de documentación y una amplia comunidad de desarrolladores por detrás que dan lo mejor de si para difundir el uso de este framework.

Es cierto que existen tutoriales para realizar casi todo lo que uno se proponga. Por lo tanto no voy a inventar la rueda y pretender que lo que diga aquí no este explicado en multitud de webs. Ese no es mi objetivo, sino el de recopilar una serie de ejemplos sobre como realizar determinadas tareas y tenerlas agrupadas en un mismo lugar. De esa manera contaré con ellas para cuando las necesite y estarán disponibles para todos aquellos interesados que por alguna razón aterricen en este espacio.

Voy a comenzar en el mismo punto donde me di cuenta que necesitaba ayuda. Estaba intentando enviar un simple email con OctoberCms y fui incapaz de hacerlo. Este tutorial es una guía de como hacerlo con Laravel.

Esta realizado siguiendo esta magnifica guía de vídeo tutoriales, publicada por Manuel J. Dávila que me ha servido para ir aprendiendo. Los mencionados vídeos están geniales pero hecho de menos un lugar donde poder consultar los códigos que ha ido mostrando el autor. Esos códigos por lo tanto los veréis aquí, exactamente los mismos, con alguna que otra pequeña modificación de mi parte. Como dije anteriormente para tenerlos a mano y para uso de cualquiera que los necesite. Sin más dilatación vamos a comenzar.

Voy a iniciar en el tutorial número 7, por las razones que ya exprese, pero sino conocen mucho de este framework os aconsejo que veáis los vídeos tutoriales desde el inicio.

  1. Abrir el fichero mail.php que se encuentra en: app/config
    El autor realiza los cambios sobre este mismo fichero pero como estoy trabajando en un entorno local lo que hice fue copiar el mismo para la carpera app/config/local.
  2. Configurarlo de la siguiente manera:
'host' => 'smtp.gmail.com',
'from' => array('address' => '[email protected]', 'name' => 'Nombre'),
'username' => 'tuusername',
'password' => 'tucontraseña',

Aquí quiero detenerme un segundo. Yo tengo configurado como aplicación de SMTP el Exim. Los datos que agreguemos en el fichero mail.php deben ser los mismos que están en la configuración del Exim, tal y como se muestra en este enlace: http://dajul.com/2009/06/08/configurar-exim4-con-gmail-o-google-apps/. De no hacerlo así a mi, al menos, no me enviaba los emails.

  1. Crear una vista para enviar el formulario que se llamará contacto.blade.php que esta en app/views. Siguiendo el tutorial la misma estaría dentro de una carpeta llamada HomeController, donde estarían esta vista y otras que se han ido creando a lo largo del tutorial:
    view-contacto
  2. Crear el formulario:
{{ Form::open(array
	(
		'action'    =>  'HomeController@contacto',
		'method'    =>  'POST',
		'role'      =>  'form',
	)) 
}}
//campos del formulario aquí....
{{ Form::close() }}

Toda la documentación al respecto la podéis ver aquí: http://laravel.com/api/4.2/

  1. Agregar los campos del formulario:
<div class="form-group">
   {{ Form::label('name', 'Nombre:') }}
   {{ Form::input('text', 'name', null, array('class' => 'form-control')) }}
</div>
<div class="form-group">
   {{ Form::label('email', 'Email:') }}
   {{ Form::input('email', 'email', null, array('class' => 'form-control')) }}
</div>
<div class="form-group">
   {{ Form::label('subject', 'Asunto:') }}
   {{ Form::input('text', 'subject', null, array('class' => 'form-control')) }}
</div>
<div class="form-group">
   {{ Form::label('msg', 'Mensaje:') }}
   {{ Form::textarea('msg', null, array('class' => 'form-control')) }}
</div>
{{ Form::input('hidden', 'contacto') }}
{{ Form::input('submit', null, 'Enviar', array('class' => 'btn btn-primary')) }}

En el vídeo solo agregan los label: {{ Form::label(‘Nombre:’) }}. Yo he agregado el atributo for al label para cuando se de clic sobre el nombre se seleccione el campo, quedando como lo veis arriba.

  1. En este momento si visualizamos nuestro formulario debería verse así:
    Comento que estoy utilizando el framework Bootstrap para dar forma e interactividad a los ejemplos.
    view-contacto-navegador
  2. Crear la plantilla del email. Las mismas están ubicadas en app/views/emails. Esta carpeta se instala por defecto en Laravel. Creamos un fichero nuevo con el nombre contacto.blade.php y le introducimos el código:
<html>
<head></head>
<body>
<p>Nombre del contacto: {{$name}}</p>
<p>Email del contacto: {{$email}}</p>
<p>Asunto: {{$subject}}</p>
<p>Mensaje:</p>
{{$msg}}
</body>
</html>
  1. Ahora le toca el turno al controlador. Esta ubicado en app/controllers y se nombra: HomeController.phpcontroller-homeController
  2. Contiene lo siguiente:
public function contacto()
	{
		$mensaje = null;
		if (isset($_POST['contacto']))
		{
			$data = array
				(
				'name'		=>	Input::get('name'),
				'email'		=>	Input::get('email'),
				'subject'	=>	Input::get('subject'),
				'msg'		=>	Input::get('msg')
				);
				$fromEmail	=	'[email protected]';
				$fromName	=	'Nombre';
				Mail::send('emails.contacto', $data, function($message) use ($fromName, $fromEmail)
				{
					$message->to($fromEmail, $fromName);
					$message->from($fromEmail, $fromName);
					$message->subject('Nuevo mensaje de contacto');
				});
				$mensaje = '<div class="text-info">Mensaje enviado con éxito</div>'; 
                  } 
                  return View::make('HomeController.contacto', array('mensaje' => $mensaje)); 
         }
  1. En la vista agregar la variable mensaje antes del inicio del formulario:
    {{$mensaje}}
  2. Antes de probar el envío debemos agregar la siguiente línea en el fichero route.php que se encuentra en: app/
Route::post('/contacto', array('as'=>'contacto', 'uses'=>'HomeController@contacto'));

En el tutorial esto no se explica, cuando lo probé me dio un error y después de buscar di con la solución. La vista contacto esta ruteada como Get, es decir, todos los parámetros se están pasando por este método y con el envío del formulario se hacen por Post, por eso da error. La solución es agregarle también a la vista ese método de envío y problema resuelto. Si alguien puede explicarlo mejor genial.

  1. Probar el envío y todo debe funcionar correctamente.

Ahora vamos a validar el formulario. Para ello tenemos que ir modificando el controlador y la vista. La documentación de este apartado la podéis consultar en: http://laravel.com/docs/4.2/validation

  1. Ir al controlador HomeController y en la acción contacto, agregar encima de la variable $data lo siguiente:
$rules = array
			(
				'name' => 'required|regex:/^[a-zA-Z\s]*$/|min:3|max:80',
				'email' => 'required|email|between:3,80',
				'subject' => 'required|regex:/^[a-zA-Z\s0-9]+$/|min:3|max:80',
				'msg' => 'required|between:3,500',
			);
  1. Crear la instancia de la clase Validator:
$validator = Validator::make(Input::All(), $rules);
  1. Crear una condicional para que si pasa la validación envié los datos o de lo contrario devuelva a la vista los errores. En estos momentos nuestra acción debería estar así:
public function contacto()
	{
		$mensaje = null;
		if (isset($_POST['contacto'])) /* Campo oculto contacto */
		{
			$rules = array
			(
				'name' => 'required|regex:/^[a-zA-Z\s]*$/|min:3|max:80',
				'email' => 'required|email|between:3,80',
				'subject' => 'required|regex:/^[a-zA-Z\s0-9]+$/|min:3|max:80',
				'msg' => 'required|between:3,500',
			);
			$validator = Validator::make(Input::All(), $rules, $messages);
			if ($validator->passes())
			{
				$data = array
				(
					'name'		=>	Input::get('name'),
					'email'		=>	Input::get('email'),
					'subject'	=>	Input::get('subject'),
					'msg'		=>	Input::get('msg')
				);
				$fromEmail	=	'[email protected]';
				$fromName	=	'escael';
				Mail::send('emails.contacto', $data, function($message) use ($fromName, $fromEmail)
				{
					$message->to($fromEmail, $fromName);
					$message->from($fromEmail, $fromName);
					$message->subject('Nuevo mensaje de contacto');
				});
				$mensaje = 'Mensaje enviado con éxito';
			}
			else 
			{
				return Redirect::back()->withInput()->withErrors($validator);
			}							
		}	
		return View::make('HomeController.contacto', array('mensaje' => $mensaje));
	}
  1. Ir a la vista contacto y cambiar donde esta:
{{ Form::input('text', 'name', null, array('class' => 'form-control')) }}

por:

{{ Form::input('text', 'name', Input::old('name'), array('class' => 'form-control')) }}
  1. Incluir los errores en la vista:
<div class="bg-danger">{{ $errors-&gt;first('name') }}</div>

Lo mismo en todos los campos

  1. Probar el formulario. Devuelve los errores en inglés, para cambiarlos a español, realizar los siguientes cambios en el controlador:
			$messages = array
			(
				'name.required' => 'El campo es requerido',
				'name.regex' => 'Solo letras y espacios',
				'name.min' => 'Mínimo de 3 caracteres',
				'name.max' => 'Máximo de 80 caracteres',
				'email.required' => 'El campo es requerido',
				'email.email' => 'El formato de email es incorrecto',
				'email.between' => 'Entre 30 y 80 caracteres',
				'subject.required' => 'El campo es requerido',
				'subject.regex' => 'Solo letras y números',
				'subject.min' => 'Mínimo de 3 caracteres',
				'subject.max' => 'Máximo de 80 caracteres',
				'msg.required' => 'El campo es requerido',
				'msg.between' => 'Entre 3 y 500 caracteres',
			);

y en la instancia de la clase Validator agregar lo siguiente:

$validator = Validator::make(Input::All(), $rules, $messages);
  1. Probar el formulario. Devuelve los errores en español.

En este punto ya nuestro formulario debería funcionar correctamente pero para mejorarlo aún faltan un par de cosillas. Por un lado hacer el envío por Ajax, ya que representa una mejora en la interfaz del usuario y agregarle un captcha para evitar que los spiders que campean por la web se den gusto enviando nuestro formulario con basuras.

  1.  Incluir id al formulario y a los campos de error, además de cambiar el input submit por un botón:
{{ Form::open(array
	(
		'action'    =>  'HomeController@contacto',
		'method'    =>  'POST',
		'role'      =>  'form',
		'id'	    =>	'form'
	)) 
}}
<div class="bg-danger" id="_name">{{ $errors->first('name') }}</div>
{{ Form::input('button', null, 'Enviar', array('class' => 'btn btn-primary', 'id' => 'btn')) }}
  1. Agregar en los meta el siguiente código:
$(function () {
		function send_ajax()
		{
			$.ajax({
				url: 	'contacto',
				type: 	'POST',
				data: 	$("#form").serialize(),
				success: function(datos)
				{
					$("#_email, #_name, #_subject, #_msg").text('');
					if (datos.success == false)
					{
						$.each(datos.errors, function(index, value)
						{
							$("#_"+index).text(value);
						});
					}
					else 
					{
						document.getElementById('form').reset();
						$("#mensaje").text('Mensaje enviado con éxito');
					}
				}  
			});
		}
		$("#btn").on("click", function()
		{
			send_ajax();
		});
	});

En el div donde se muestra el mensaje de enviado agregarle el siguiente id:

<div id="mensaje" class="bg-info">{{$mensaje}}</div>

Que es donde se va a pintar el mensaje de enviado.

  1. Ir al controlador y donde se capturan los errores agregar el siguiente código:
if (Request::ajax())
					{
						return Response::json
						([
							'success' => false,
							'errors'  => $validator->getMessageBag()->toArray()
						]);
					}
					else 
					{
						return Redirect::back()->withInput()->withErrors($validator);
					}

Incluir un captcha de google

  1. Instalar el captcha desde el repositorio: https://github.com/greggilbert/recaptcha
  2. Agregar al composer.json la siguiente línea:
"greggilbert/recaptcha": "dev-master"
  1. Ir al terminal y teclear la siguiente sentencia:
composer composer update --dev

A continuación:

  1. Ir la carpeta local ubicada dentro de config, para utilizar el de nuestro entorno local, en el fichero app.php donde tenemos los provedores agregamos lo siguiente:
'Greggilbert\Recaptcha\RecaptchaServiceProvider'

Vamos nuevamente al terminal y ejecutamos

php artisan config:publish greggilbert/recaptcha

Abrimos el fichero app/config/packages/greggilbert/recaptcha/config.php y veremos que necesitamos incluir dos claves, una publica y otra privada. Para ellos vamos a Google, damos click en GetRecaptcha, nos registramos, agregamos nuestro entorno local en la url, si estamos trabajando sobre localhost o 127.0.0.1 nos sirve cualquier sitio nuestro. Yo tuve que poner mi virtualhost para que me funcionara. Una vez hecho esto nos da nuestras claves publicas y privadas para agregarlas al config.php del recaptcha.

  1. Ir la carpeta de lenguaje ubicada en app/lang/en/ y en el fichero validation.php, agregar al final la siguiente línea:
"recaptcha" => 'The :attribute field is not correct.',
  1. Ir la vista de contacto y al final del textarea de mensaje agregar:
{{ Form::captcha() }}
<div class="bg-danger" id="_recaptcha_response_field">{{ $errors->first('recaptcha_response_field') }}</div>

En el script del cabezal agregar el identificador en:

$("#_email, #_name, #_subject, #_msg, #_recaptcha_response_field").text('');
  1. En el controlador agregar la reglas de validación y los mensajes en español:
'recaptcha_response_field' => 'required|recaptcha',
'recaptcha_response_field.required' => 'El campo captcha es requerido',
'recaptcha_response_field.recaptcha' => 'Captcha incorrecto',

Para ir terminando esta interminable entrada voy a dejar los códigos completos de la vista y del controlador:

Vista:

<div id="mensaje" class="bg-info">{{$mensaje}}</div> 

{{ Form::open(array
 (
 'action' => 'HomeController@contacto',
 'method' => 'POST',
 'role' => 'form',
 'id' => 'form'
 )) 
}}

<div class="form-group">
 {{ Form::label('name', 'Nombre:') }}
 {{ Form::input('text', 'name', Input::old('name'), array('class' => 'form-control')) }}
 <div class="bg-danger" id="_name">{{ $errors->first('name') }}</div>
</div>

<div class="form-group">
 {{ Form::label('email', 'Email:') }}
 {{ Form::input('email', 'email', Input::old('email'), array('class' => 'form-control')) }}
 <div class="bg-danger" id="_email">{{ $errors->first('email') }}</div>
</div>

<div class="form-group">
 {{ Form::label('subject', 'Asunto:') }}
 {{ Form::input('text', 'subject', Input::old('subject'), array('class' => 'form-control')) }}
 <div class="bg-danger" id="_subject">{{ $errors->first('subject') }}</div>
</div>

<div class="form-group">
 {{ Form::label('msg', 'Mensaje:') }}
 {{ Form::textarea('msg', Input::old('msg'), array('class' => 'form-control')) }}
 <div class="bg-danger" id="_msg">{{ $errors->first('msg') }}</div>
</div>

{{ Form::captcha() }}
<div class="bg-danger" id="_recaptcha_response_field">{{ $errors->first('recaptcha_response_field') }}</div>

{{ Form::input('hidden', 'contacto') }}
{{ Form::input('button', null, 'Enviar', array('class' => 'btn btn-primary', 'id' => 'btn')) }}
 
{{ Form::close() }}

Script JS de la vista:

$(function () {
	function send_ajax()
	{
		$.ajax({
			url: 	'contacto',
			type: 	'POST',
			data: 	$("#form").serialize(),
			success: function(datos)
			{
				$("#_email, #_name, #_subject, #_msg, #_recaptcha_response_field").text('');
				if (datos.success == false)
				{
					$.each(datos.errors, function(index, value)
					{
						$("#_"+index).text(value);
					});
				}
				else 
				{
					document.getElementById('form').reset();
					$("#mensaje").text('Mensaje enviado con éxito');
				}
			}  
		});
	}
	$("#btn").on("click", function()
	{
		send_ajax();
	});
});

Controlador:

public function contacto()
{
	$mensaje = null;
	if (isset($_POST['contacto'])) /* Campo oculto contacto */
	{
		$rules = array
		(
			'name' => 'required|regex:/^[a-zA-Z\s]*$/|min:3|max:80',
			'email' => 'required|email|between:3,80',
			'subject' => 'required|regex:/^[a-zA-Z\s0-9]+$/|min:3|max:80',
			'msg' => 'required|between:3,500',
			'recaptcha_response_field' => 'required|recaptcha',
		);
		$messages = array
		(
			'name.required' => 'El campo es requerido',
			'name.regex' => 'Solo letras y espacios',
			'name.min' => 'Mínimo de 3 caracteres',
			'name.max' => 'Máximo de 80 caracteres',
			'email.required' => 'El campo es requerido',
			'email.email' => 'El formato de email es incorrecto',
			'email.between' => 'Entre 30 y 80 caracteres',
			'subject.required' => 'El campo es requerido',
			'subject.regex' => 'Solo letras y números',
			'subject.min' => 'Mínimo de 3 caracteres',
			'subject.max' => 'Máximo de 80 caracteres',
			'msg.required' => 'El campo es requerido',
			'msg.between' => 'Entre 3 y 500 caracteres',
			'recaptcha_response_field.required' => 'El campo captcha es requerido',
			'recaptcha_response_field.recaptcha' => 'Captcha incorrecto',
		);
		$validator = Validator::make(Input::All(), $rules, $messages);
		if ($validator->passes())
			{
				$data = array
				(
					'name'		=>	Input::get('name'),
					'email'		=>	Input::get('email'),
					'subject'	=>	Input::get('subject'),
					'msg'		=>	Input::get('msg')
				);
				$fromEmail	=	'[email protected]';
				$fromName	=	'Nombre';
				Mail::send('emails.contacto', $data, function($message) use ($fromName, $fromEmail)
				{
					$message->to($fromEmail, $fromName);
					$message->from($fromEmail, $fromName);
					$message->subject('Nuevo mensaje de contacto');
				});
				$mensaje = 'Mensaje enviado con éxito';
			}
			else 
			{
				if (Request::ajax())
				{
					return Response::json
					([
						'success' => false,
						'errors'  => $validator->getMessageBag()->toArray()
					]);
				}
				else 
				{
					return Redirect::back()->withInput()->withErrors($validator);
				}
			}
		}
	return View::make('HomeController.contacto', array('mensaje' => $mensaje));
}

Si tenéis alguna duda de como funciona algo dentro del código os aconsejo que veáis los tutoriales, ahí todo esta explicado al detalle.

The post Enviar emails con Laravel first appeared on Escael Marrero.]]>
Instalar OctoberCms en Ubuntu https://www.escael.com/instalar-octobercms-en-ubuntu/ Fri, 24 Oct 2014 17:20:04 +0000 http://www.escael.com/?p=531 Siguiendo con las guías que me he propuesto hacer, ahora le toca el turno a OctoberCms un CMS basado en Laravel, un framework que esta sonando últimamente. Los requisitos para instalar el mismo son los siguiente: PHP 5.4 o superior con las restricciones de safe_mode desabilitadas. La extensión PDO de PHP. La extensión cURL de PHP. La extensión MCrypt de […]

The post Instalar OctoberCms en Ubuntu first appeared on Escael Marrero.]]>
Siguiendo con las guías que me he propuesto hacer, ahora le toca el turno a OctoberCms un CMS basado en Laravel, un framework que esta sonando últimamente. Los requisitos para instalar el mismo son los siguiente:

  1. PHP 5.4 o superior con las restricciones de safe_mode desabilitadas.
  2. La extensión PDO de PHP.
  3. La extensión cURL de PHP.
  4. La extensión MCrypt de PHP.
  5. La librería ZipArchive de PHP.
  6. La librería GD de PHP.

Exceptuando la 3 y la 4, todas las tenía ya instaladas. Por lo tanto voy a explicar esas dos. Quiero aclarar que los pasos que doy son los que a mi me funcionaron, lo que significa que a otras personas lo hayan solucionado por otra vía.

Para instalar MCrypt:

  1. sudo apt-get install mcrypt
  2. Si es necesario instalar este paquete también:php5-mcrypt. En mi caso ya estaba instalado.
    sudo apt-get install php5-mcrypt
  3. sudo /etc/init.d/apache2 restart

Para instalar cURL:

  1. sudo apt-get install php5-curl
  2. sudo /etc/init.d/apache2 restart

Con esto ya tenemos listo el servidor para configurar el virtual host.

  1. Crear el fichero de virtual host:
    sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/example.com.conf
  2. sudo vi /etc/apache2/sites-available/example.com.conf
  3. Insertar las siguientes líneas:
 <VirtualHost *:80>
    ServerAdmin webmaster@localhost
    ServerName example.com
    ServerAlias example.com
    DocumentRoot /var/www/html/example.com
    <Directory /var/www/html/example.com>
       AllowOverride All
       Require all granted
       Order allow,deny
       Allow from all
    </Directory>
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
  1. Salvar y cerrar el fichero.
  2. Escribir el siguiente comando:
    sudo a2ensite example.com.conf
  3. sudo service apache2 restart
  4. Si necesitáis activer el modulo mod_rewrite de Apache:
    sudo a2enmod rewrite
  5. sudo /etc/init.d/apache2 restart
  6. En mi caso como se trata de una máquina virtual tuve que editar el fichero host del mac, ubicado en: /etc/hosts
    sudo vi /etc/hosts
  7. Agregar la dirección ip de la máquina virtual al virtualhost que acabamos de crear:
    tu ip    ejemplo.com
  8. Ahora si tecleamos en el navegador:http://example.com debería responder el directorio del ejemplo que hemos creado.

Por último para instalar OctoberCms necesitáis composer, los pasos para instalarlo son los siguientes:

  1. curl -sS https://getcomposer.org/installer | php
  2. php composer.phar
  3. sudo mv composer.phar /usr/local/bin/
  4. alias composer=’/usr/local/bin/composer.phar’

Una vez hecho esto ya estamos listos para instalar OctoberCms:

  1. Instalar git:
    sudo apt-get install git-core
  2. A continuación utilizando composer nos descargamos del repositorio en Gihub la rama master de OctoberCms:
    composer create-project october/october october dev-master
  3. Abrimos el fichero app/config/app.php y en el apartado «url» configuramos lo siguiente:
    ‘url’ => ‘http://example.com’
  4. Podéis revisar las demás configuraciones como el thema a usar y la url al backend.
  5. Vamos al PhpMyAdmin y creamos una base de datos con el nombre que queramos.
  6. Editamos el fichero app/config/database.php y en el apartado de MySql le ponemos nuestros datos.
  7. Finalmente escribimos en el terminal lo siguiente:
    php artisan october:up

Los permisos para ejecutar correctamente OctoberCms son los siguientes:

sudo chown -R root:www-data app/storage
sudo chown -R root:www-data themes
sudo chown -R root:www-data uploads

sudo chmod -R 775 app/storage/
sudo chmod -R 775 themes
sudo chmod -R 775 uploads

En estas url puede encontrar más información sobre todo este proceso:

The post Instalar OctoberCms en Ubuntu first appeared on Escael Marrero.]]>
Instalar y configurar PhpMyAdmin en Ubuntu https://www.escael.com/instalar-y-configurar-phpmyadmin-en-ubuntu/ https://www.escael.com/instalar-y-configurar-phpmyadmin-en-ubuntu/#comments Wed, 22 Oct 2014 22:15:07 +0000 http://www.escael.com/?p=512 Hace unos días tuve que instalar una maquina virtual de Ubuntu en mi Mac. Debido a la última actualización de este sistema operativo, el de Mac (Yosemite), se me corrompieron las bases de datos en MySql. Motivo por el cual me decidí a virtualizar para garantizar que todos mis proyectos estuvieran seguros y a buen recaudo. Siguiendo el […]

The post Instalar y configurar PhpMyAdmin en Ubuntu first appeared on Escael Marrero.]]>
Hace unos días tuve que instalar una maquina virtual de Ubuntu en mi Mac. Debido a la última actualización de este sistema operativo, el de Mac (Yosemite), se me corrompieron las bases de datos en MySql. Motivo por el cual me decidí a virtualizar para garantizar que todos mis proyectos estuvieran seguros y a buen recaudo.

Siguiendo el consejo de mi buen amigo Roger voy a empezar a crear una serie de post relacionados con todo el proceso que cualquier desarrollador web se tiene que enfrentar en su día a día.

Como se titula esta entrada vamos a configurar PhpMyadmin, proceso bastante sencillo.

  1. Instalar Tasksel. Herramienta muy útil para instalar grupos de paquetes relacionados.
    Comando: sudo apt-get install tasksel
  2. Instalar PhpMyAdmin.
    Comando: sudo apt-get install phpmyadmin phpmyadmin A continuación se siguen los pasos que se indican: phpmyadmin-1
  3. Una vez completado el proceso hay que decirle a apache que llame a la configuración de PhpMyAdmin:
    Comando: sudo gedit /etc/apache2/apache2.conf
  4. Agregar la siguiente línea al final del fichero:
    Include /etc/phpmyadmin/apache.conf
  5. Reiniciamos apache:
    Comando: sudo /etc/init.d/apache2 restart
  6. Por último tecleamos en un navegador:
    http://localhost/phpmyadmin y debería cargarnos: phpmyadmin-2

Y eso es todo, espero os sirva.

The post Instalar y configurar PhpMyAdmin en Ubuntu first appeared on Escael Marrero.]]>
https://www.escael.com/instalar-y-configurar-phpmyadmin-en-ubuntu/feed/ 1
Cortar textos largos https://www.escael.com/cortar-textos-largos/ Sat, 21 Jun 2014 23:39:32 +0000 http://www.escael.com/?p=486 Como ya sabéis he estado trabajando en una versión móvil de un thema de WordPress para mi sitio Isliada. El mismo ya esta avanzado y cuando tenga un poco de tiempo voy a escribir con detalle sobre como lo he ido desarrollando. Pero resulta que acabo de encontrarme con una necesidad y la solución ha sido tan […]

The post Cortar textos largos first appeared on Escael Marrero.]]>
Como ya sabéis he estado trabajando en una versión móvil de un thema de WordPress para mi sitio Isliada. El mismo ya esta avanzado y cuando tenga un poco de tiempo voy a escribir con detalle sobre como lo he ido desarrollando. Pero resulta que acabo de encontrarme con una necesidad y la solución ha sido tan simple que no puedo esperar a contarla.

Estaba trabajando en un módulo que muestra los autores que escriben en el mismo, quería hacerlo como una galería de imágenes donde se mostrarán las fotos y debajo los nombres de los autores. Al tener tan poco espacio como el presente en casi todos los dispositivos móviles, algunos nombres ocupaban una línea pero había algunos que ocupaban dos. Muestro un ejemplo:

cortar-textos

Como resolver el problema. Sencillamente cortando los caracteres y agregando a los largos tres puntos suspensivos (…) para informar al usuario que ese texto es más largo pero que por problemas de espacio no se muestra. La usabilidad ante todo.

Existen varias formas para hacer esto. Primero pensé realizarlo con PHP, usando la función mb_substr se puede fácilmente establecer la cantidad de caracteres que uno quiere mostrar y con una simple condicional a los más largos agregarle los puntos suspensivos. Esto en un principio me funciono, pero no debemos olvidar que hay dispositivos de tamaños variables, en algunos casos cuadraban los caracteres, en otros al ser más pequeños volvía nuevamente a ocuparme más de una línea.

Entonces pensé hacerlo con CSS que al fin y al cabo es lo que más domino. Para ello podemos usar la propiedad text-overflow que dentro de sus valores tiene uno que se llama ellipsis, que hace exactamente eso: agrega tres puntos suspensivos al final del texto. Su uso completo es el siguiente:

white-space: 			nowrap;
overflow: 			hidden;
-ms-text-overflow: 	ellipsis;
-o-text-overflow: 	        ellipsis;
text-overflow: 		ellipsis;

La propiedad white-space establece el uso de los espacios en blanco que junto a nowrap elimina los espacios en blanco. El overflow hace que lo que sobresalga del contenedor se oculte, es una propiedad bastante conocida. Text-overflow por su parte define que hacer con esos elementos o caracteres en este caso cuando se desborda y entre sus valores existe el ellipsis.

Hasta aquí todo perfecto pero ya que estoy usando Compass supuse que existía algo en ese maravilloso framework que hiciera algo parecido y efectivamente! Usando una simple línea el problema queda resuelto:

@include ellipsis;

El framework genera el código CSS arriba mostrado, algo tan simple y que te ahorra un montón de tiempo. Otra razón más para estar muy a gusto con esta tecnología.

The post Cortar textos largos first appeared on Escael Marrero.]]>
Versión móvil en thema de WordPress https://www.escael.com/version-movil-en-thema-de-wordpress/ Sat, 17 May 2014 15:18:14 +0000 http://www.escael.com/?p=475 Acabo de comenzar un nuevo proyecto que tiene todas las pintas de ser muy interesante. Se trata de la creación de una versión móvil de este sitio: www.isliada.org, el cual es un proyecto personal junto con unos amigos editores. El thema de ese sitio fue realizado completamente desde cero, en aquellos momentos no utilizaba ni […]

The post Versión móvil en thema de WordPress first appeared on Escael Marrero.]]>
Acabo de comenzar un nuevo proyecto que tiene todas las pintas de ser muy interesante. Se trata de la creación de una versión móvil de este sitio: www.isliada.org, el cual es un proyecto personal junto con unos amigos editores. El thema de ese sitio fue realizado completamente desde cero, en aquellos momentos no utilizaba ni SASS ni LESS y menos Compass, así que lo maquete con CSS3 directamente.

Resulta que ahora he querido realizar una versión móvil del mismo y para ello me he auxiliado en un plugin muy interesante: el Any Mobile Theme Switcher que fundamentalmente lo que hace es identificar el User Agent y cargar un thema según se haya escogido previamente:

Any Mobile Theme Switcher

Me parece muy interesante y sobre todo sencillo de usar. Probé varios pero algunos traían demasiadas opciones (themas por defecto unos y demasiadas opciones de configuración y otros themas dentro del mismo plugin cosa que no me gustaba mucho. Prefiero tener los elementos agrupados por su funcionalidad, no regados por ahí).

Una vez escogido el plugin, instalado y hechas las primeras pruebas he configurado el thema móvil para su puesta en marcha. Primero cree el proyecto con Compass utilizando Susy:

 compass create --using susy islidaMobil

Esto crea todos los ficheros necesarios para comenzar a trabajar.

Segundo he decidido usar Bundle como explique en el anterior post. El mismo consta de la siguiente configuración:

gem 'sass', "3.3.7"
gem 'compass', "1.0.0.alpha.19"
gem 'susy', '2.1.2'

No es necesario cargar Compass para utilizar esta versión de Susy pero es posible que lo utilice, ya veré más adelante.

Otro aspecto que quiero destacar es una pequeña modificación en el fichero de configuración de Compass, el config.rb. Este fichero como su nombre lo indica es el encargado de compilar los ficheros SASS en CSS. Pues bien, la estructura de directorios que crea Compass es algo así:

directory isliadaMobile/sass/ 
directory isliadaMobile/stylesheets/ 
   create isliadaMobile/config.rb 
   create isliadaMobile/sass/_grids.scss 
   create isliadaMobile/sass/style.scss 
   create isliadaMobile/stylesheets/style.css 

Lo que en principio esta muy bien pero sucede que WordPress necesita un fichero style.css en la raíz del directorio del thema para funcionar correctamente. Por lo tanto necesitaba que el fichero CSS que se compilaba en el directorio stylesheets se copiara en la raíz, para ello es necesario agregar este pequeño código al config.rb:

require 'fileutils'
on_stylesheet_saved do |file|
  if File.exists?(file) && File.basename(file) == "style.css"
    puts "Moving: #{file}"
    FileUtils.mv(file, File.dirname(file) + "/../" + File.basename(file))
  end
end

que hace exactamente eso.

Y bueno ya tengo listo todo para comenzar a programar tanto con PHP como con SASS. Estoy emocionado por probar la nueva versión de Susy, promete mucho. Todo lo que vaya aprendiendo lo iré posteando para todos aquellos que os interese.

The post Versión móvil en thema de WordPress first appeared on Escael Marrero.]]>
Sobre el proyecto Artesabaking https://www.escael.com/sobre-el-proyecto-artesabaking/ Fri, 16 May 2014 22:14:41 +0000 http://www.escael.com/?p=468 He dejado un poco abandonado este apartado de mi portfolio, la pereza al escribir es un mal que me ataca de vez en cuando pero al que he decidido ponerle fin. Me surgen muchos temas a tocar pero ninguno mejor como explicar algunas de los proyectos que he ido realizando, exponerlos me hace ver mejor […]

The post Sobre el proyecto Artesabaking first appeared on Escael Marrero.]]>
He dejado un poco abandonado este apartado de mi portfolio, la pereza al escribir es un mal que me ataca de vez en cuando pero al que he decidido ponerle fin. Me surgen muchos temas a tocar pero ninguno mejor como explicar algunas de los proyectos que he ido realizando, exponerlos me hace ver mejor los errores y los logros que he conseguido con ellos.

El último proyecto que casi concluyo es Artesabaking, una web de una tienda de dulces estadounidense, digo casi porque aún quedan algunos ajustes por realizar, detalles sobre todo y algunas vistas llevarlas a RWD. He empleado «SASS 3.2.9», «compass 0.12.2» y el plugin «compass-960-plugin 0.10.4». Cuando comencé a preparar las condiciones para la maquetación pensé hacerlo utilizando Susy pero me percaté que había una nueva versión de SASS y otra de Susy, y al actualizarlas empezaron los problemas. Según la documentación de Susy cuando vas a comenzar un proyecto debes tirar la siguiente línea:

compass create –using susy <project name>

en la misma utilizando compass creas un proyecto con Susy, pero eso me dio error. No era posible crear un proyecto porque Susy 2 depende de SASS 3.3.0 y la versión que tenía de Compass (para compilar) era la 0.12.2. Pues sencillo actualizaba compass y listo. En ese momento la versión estable de compass es la que he nombrado anteriormente, pero los desarrolladores tienen una versión release (1.0.0.alpha.19) que instalando mediante el siguiente comando funcionaría:

gem install compass –pre

pero no amigos, eso me dio otro error, esta vez de Ruby. Para no hacer muy extensiva esta explicación decidí utilizar compass-960-plugin como grid para maquetar y volver a las versiones anteriores de SASS. Un tiempo después logre solucionar el problema de Ruby que no era otro que actualizar a una versión superior, ahora no recuerdo los pasos pero no fueron muy complejos. En fin que instale la versión alpha de compass y de ahí en adelante todo fue de maravillas. El problema que restaba solucionar era como terminar este proyecto, del cual aún no he dicho nada, con las versiones que lo comencé. Para solucionar este detalle vino en mi ayuda Bundler, el cual permite instalar las versiones de diferentes gemas de ruby para cada proyecto en particular. Un ejemplo sería:

source "https://rubygems.org"
gem 'sass', "3.2.9"
gem 'compass', "0.12.2"
gem 'compass-960-plugin', '0.10.4'

eso en un fichero de configuración llamado Gemfile y ubicado en la raíz del proyecto, descarga e instala las versiones que va a necesitar el mismo. Esta practica es muy recomendable sobre todo cuando se trabaja en muchos proyectos que se van quedando «atrasados» y en algún instante es necesario tocarlos.

Bueno y que decir sobre Artesabaking, aparte de ser un diseño muy complejo y bonito fruto de la imaginación de un gran diseñador como es Iván Santamaría, el cual me puso a pensar en más de una ocasión en como solucionar los retos que me planteaba. Puro HTML5 con una marcado semántico aplicando la metodología BEM. Y por último gracias a la magia de SASS y compass pude darle salida a este bello trabajo y con un código que considero de muy buena calidad. Todo versionado con Git para tener un respaldo en todo momento de las modificaciones y estados de códigos.

He utilizado varias de las funcionalidades de SASS como por ejemplo el uso de EACH:

$i: 1;
@each $icon in gift, pizza, clock {
&:nth-child(#{$i}):before {
@include sprite-background("sprites/#{$icon}.png", 90px, 80px);
background-position: center;
background-color: #8f69ec;
}
$i: $i + 1;
}

eso lo utilice en la página de services para pintar el módulo que veis abajo a la izquierda.

Me he extendido hablando un poco sobre los problemas que me encontré en este proyecto pero me siento bien porque al final logre solucionarlos y configurar el ordenador correctamente, además ya tengo un método para futuros trabajos. Si alguno de vosotros tiene problemas parecidos no dude en escribirme o dejar un comentario, estaré encantado de transmitirle mi experiencia.

The post Sobre el proyecto Artesabaking first appeared on Escael Marrero.]]>
Bootstrap ¡al fin con Sass! https://www.escael.com/bootstrap-al-fin-con-sass/ Sat, 01 Feb 2014 00:16:17 +0000 http://www.escael.com/?p=400 La noticia me ha sorprendido, hace unas horas Booststrap el conocido framework de desarrollo frontend acaba de realizar una actualización que venía esperando hace mucho tiempo. ¡Han incluido un repositorio oficial de Sass en su framework! Como muchos conocéis Bootstrap esta desarrollado con Less y aunque este pre-procesador de css es muy bueno, para muchos […]

The post Bootstrap ¡al fin con Sass! first appeared on Escael Marrero.]]>
La noticia me ha sorprendido, hace unas horas Booststrap el conocido framework de desarrollo frontend acaba de realizar una actualización que venía esperando hace mucho tiempo. ¡Han incluido un repositorio oficial de Sass en su framework!

Como muchos conocéis Bootstrap esta desarrollado con Less y aunque este pre-procesador de css es muy bueno, para muchos entre ellos un servidor, echábamos de menos la posibilidad de jugar con este framework utilizando Sass, pues hoy este anhelo se ha materializado.

Por último y como curiosidad. En mi trabajo oficial, ese que vamos todas las mañanas con sueño después de pasar varias horas nocturnas haciendo proyectos y desarrollos propios, vengo desarrollando con Bootstrap hace unos meses, maldiciendo en muchas ocasiones las limitaciones que a mi entender tiene Less, y justo hoy, cuando termino el proyecto que me mantenía ocupado veo la noticia que os he dado arriba. Podrán imaginarse mi cara de sorpresa, el destino a veces te juega bromas pesadas. Pues nada, tendré que esperar unos meses cuando se decida pasar a una versión superior del proyecto mencionado para empezar disfrutar de Sass.

The post Bootstrap ¡al fin con Sass! first appeared on Escael Marrero.]]>