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:
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.]]>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:
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.]]>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:
Hasta aquí tenemos instalado NodeJs. Ahora instalamos 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.
Esta línea no la tengo muy clara, pero basicamente ejecuta npm a nivel local:
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:
Por último creamos un enlace simbólico de NodeJs a 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:
Una vez hecho podremos instalar Gulp a nivel global. Fijarse que no usamos sudo:
Verificamos que Gulp.js ha sido instalado correctamente.
Si esta correcto saldrá algo así:
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:
A continuación tecleamos la instrucción:
que nos pedirá los datos de nuestro proyecto y lo vamos rellenando según nuestra información.
Para instalar gulp en el proyecto local:
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:
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.
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.
'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.
{{ 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/
<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.
<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>
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)); }
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.
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
$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);
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)); }
{{ Form::input('text', 'name', null, array('class' => 'form-control')) }}
por:
{{ Form::input('text', 'name', Input::old('name'), array('class' => 'form-control')) }}
<div class="bg-danger">{{ $errors->first('name') }}</div>
Lo mismo en todos los campos
$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);
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.
{{ 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')) }}
$(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.
if (Request::ajax()) { return Response::json ([ 'success' => false, 'errors' => $validator->getMessageBag()->toArray() ]); } else { return Redirect::back()->withInput()->withErrors($validator); }
Incluir un captcha de google
"greggilbert/recaptcha": "dev-master"
composer composer update --dev
A continuación:
'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.
"recaptcha" => 'The :attribute field is not correct.',
{{ 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('');
'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.]]>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:
Para instalar cURL:
Con esto ya tenemos listo el servidor para configurar el virtual host.
<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>
Por último para instalar OctoberCms necesitáis composer, los pasos para instalarlo son los siguientes:
Una vez hecho esto ya estamos listos para instalar OctoberCms:
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.]]>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.
Y eso es todo, espero os sirva.
The post Instalar y configurar PhpMyAdmin en Ubuntu first appeared on Escael Marrero.]]>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:
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.]]>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:
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.]]>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.]]>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.]]>