Archivo de la categoría: programación

Instalar sassC en un contenedor de Docker

En el repositorio de Git de sassC podemos encontrar las instrucciones para instalarlo en nuestro ordenador:

git clone https://github.com/sass/libsass.git
export SASS_LIBSASS_PATH=/Users/you/path/libsass
git clone https://github.com/sass/sassc.git
cd ./sassc
make

Si estamos usando el Fish shell, en vez del export de la segunda línea, utilizaremos:

set -x SASS_LIBSASS_PATH /Users/you/path/libsass

Ahora tenemos que convertir estas instrucciones al formato que acepta nuestro Dockerfile que usaremos para configurar el contenedor:

RUN mkdir -p /root/sass
WORKDIR /root/sass
RUN git clone https://github.com/sass/libsass.git \
    && git clone https://github.com/sass/sassc.git
ENV SASS_LIBSASS_PATH /root/sass/libsass
WORKDIR /root/sass/sassc
RUN make

Error “TypeError: oldKeypath is undefined” en Ractive.js

Este es uno de esos raros casos en los que buscas un error en Google y no obtienes ningún resultado. El error es el siguiente:

TypeError: oldKeypath is undefined

Haciendo un poco de investigación descubrí que el causante del error era este input en una plantilla de Ractive.js.

<input type="hidden" name="element_order[]" value="{{ index + 1 }}">

El problema consiste en que realizo modificaciones en el orden de los elementos y también pueden ser eliminados. Ractive.js al hacer una vinculación an ambos sentidos del valor del input que contiene el índice actual, parece ser que no le gusta y lanza el error. La solución pasa por indicar a Ractive.js que no vincule el valor del input con el atributo twoway="false":

<input type="hidden" name="element_order[]" value="{{ index + 1 }}" twoway="false">

Valor por defecto para un parametro de una función en JavaScript

Es fácil encontrar la solución a esto, por ejemplo en StackOverflow, pero la he buscado ya tantas veces que he decidido dejarla aquí anotada:

function sampleFunction( sampleParameter ) {
    sampleParameter = typeof sampleParameter !== 'undefined' ? sampleParameter : false;
}

En el ejemplo comprobamos si el parámetro está definido, y en caso de que no lo esté le asignamos el valor false por defecto.

Generador de rango de color

Algo que siempre he encontrado difícil cuando trabajo en la parte visual de una aplicación web es encontrar el color adecuado para cada componente. A veces tienes un color base sobre el que quieres trabajar y quieres tener variaciones más claras o más oscuras de ese color. He encontrado algunas webs que ofrecen generar rangos de colores, pero suelen ser bastante farragosas y complicadas.

Así que como hago siempre en este tipo de situaciones, he creado mi propia aplicación para generar un rango de colores.

Generador de rango de colores

Como su nombre indica, a partir de un color base la aplicación genera un rango de colores más claros y más oscuros que el original.

El algoritmo javascript utilizado es creación de Pimp Trizkit, creado para responder a su propia pregunta en este hilo de StackOverflow.

Subir ficheros al FTP de manera individual con PhpStorm

Para poder subir ficheros al FTP con PhpStorm, tanto de manera individual como en grupo, esto es lo que tenemos que hacer. Vamos a:

Tools -> Deployment -> Configuration...

Pinchamos sobre el más + para añadir una nueva configuración. Le damos nombre y seleccionamos el tipo, y a continuación introducimos todos los datos de la conexión.

Pinchamos en el botón para comprobar que la configuración es correcta y revisamos que en la pestaña de Mappings tenemos todas las rutas introducidas.

Después en el explorador de ficheros, podemos pinchar sobre uno con el botón derecho y hacer:

Deployment -> Upload to <nombre del servidor>

Añadir número de versión a el CSS compilado por Compass

Por ejemplo, si nuestro fichero principal se llama styles.scss, tras la compilación de Compass obtendremos un fichero llamado styles.css. Nuestro objetivo sería entonces que el fichero generado fuese del estilo styles-3.2.4.min.css, que es lo que necesitamos para el servidor de producción.

Supongamos que tenemos el número de versión actual en el fichero version.json, con esta estructura:

{
    "version": "3.2.4"
}

Lo que debemos hacer es, en el fichero config.rb, leer el contenido de este fichero y crear el nuevo fichero que incluya la versión.

require 'fileutils'
require 'json'

versionFileContent = File.read('version.json')
versionParameters = JSON.parse(sVersionFileContent)

on_stylesheet_saved do |file|
    if File.exists?(file)
        filename = File.basename(file, File.extname(file))
        FileUtils.cp(file, css_dir + '/' + filename + '-' + versionParameters['version'] + '.min' + File.extname(file))
    end
end

Observando el evento on_stylesheet_saved de Compass obtenemos acceso al fichero creado, y podemos trabajar con el para componer el nombre que queramos y guardarlo.

Un parámetro de la directiva de AngularJS tiene valor undefined

Estaba modificando una directiva de un tercero y me estaba volviendo loco con un valor que siempre estaba undefined. La directiva era sencilla y no entendía cual era el error.

La definición del scope dentro de la directiva es esta:

scope: {
  searchParam: '=ngModel',
  suggestions: '=data',
  onType: '=onType',
  formId: '=formId',
  onSelect: '=onSelect',
  autocompleteRequired: '='
}

Y el uso de la directiva es este:

<autocomplete
    ng-model="vm.sCompanyName"
    data="vm.aInsuranceCompanies"
    form-id="bikeInsuranceAlert"
    on-type="vm.autocompleteChange">
</autocomplete>

El valor que me interesa obtener es el formId. ¿Veis el error? Es sutil…

form-id="'bikeInsuranceAlert'"

Faltaban unas comillas simples dentro de las dobles para obtener el valor del ID como una cadena. Lo que AngularJS estaba interpretando es que quería obtener el valor de una variable llamada bikeInsuranceAlert dentro del scope. Evidentemente esta variable no existe, y el valor asignado era undefined.

Que traicionero es AngularJS en ocasiones…

Como resolver conflictos entre dos ramas remotas de un repositorio y su bifurcación (fork) en Git

La situación es la siguiente: Tenemos un repositorio remoto en Bitbucket que es el principal, y después tenemos una bifurcación (fork) para cada desarrollador, los cuales suben sus cambios mediante solicitudes de integración (pull request). El problema surge al intentar sincronizar ramas entre los distintos repositorios y aparecen conflictos en remoto.

Solucionar este tipo de conflictos en local es sencillo mediante por ejemplo NetBeans, por lo que la solución pasa por convertir el conflicto remoto en un conflicto local.

Supongamos que la rama conflictiva es feature/nueva-funcionalidad

1. Configuramos el repositorio principal como repositorio remoto

git remote add upstream https://Usuario@bitbucket.org/Propietario/Repositorio-principal.git
git fetch upstream

2. Nos situamos en nuestra rama local

git checkout feature/nueva-funcionalidad

3. Obtenemos los posibles cambios desde nuestro repositorio remoto bifurcado

git merge origin/feature/nueva-funcionalidad

4. Obtenemos los cambio del repositorio principal

git merge upstream/feature/nueva-funcionalidad

5. Aquí aparecerán los conflictos que nos impedían hacer el merge entre repositorios remotos. Resolvemos los conflictos y los anotamos (commit). Al terminar ya podemos subir los cambios a nuestro repositorio remoto bifurcado.

git push origin feature/car-insurance-alert

 

curl_setopt(): CURLOPT_FOLLOWLOCATION cannot be activated when an open_basedir is set

El mensaje de error completo es este:

Severity: Warning
Message:  curl_setopt(): CURLOPT_FOLLOWLOCATION cannot be activated when an open_basedir is set
Filename: src/Mandrill.php
Line Number: 68

Este es un problema conocido de la API PHP de Mandrill, y existe un Pull Request con la solución creado en abril de 2014, pero por el motivo que sea, no han añadido la corrección al repositorio principal.

Yo utilizo Composer y Packagist para gestionar las dependencias en mis proyectos, por lo que como solución temporal puedes modificar el fichero Mandrill.php con las correcciones, pero esto significa repetir el mismo proceso en todos los entornos de desarrollo, y es fácil olvidarse de hacerlo cuando han pasado unos meses.

Como solución más robusta, he creado un fork the la librería de Mandrill, y la he subido a Packagist para que pueda ser usada. Es tan sencillo como añadir esto a tus "require" en el composer.json:

"carlos_llongo/mandrill": "dev-master"

O también puedes usar:

composer require "carlos_llongo/mandrill:dev-master"

Guardar una cookie con JavaScript puro

AngularJS tiene un módulo para guardar cookies, pero por desgracia no permite establecer la fecha de expiración de la cookie, por lo que la cookie es borrada al final de la sesión.

Hay plugins para AngularJS y para JQuery que permite crear cookies de forma sencilla y establecer la fecha de expiración, pero no quería añadir una libraría más solo para guardar una cookie. Así que esta es la forma de hacerlo usando únicamente JavaScript puro:

var dExpirationDate = new Date();
dExpirationDate.setTime(dExpirationDate.getTime() + (365*24*60*60*1000));
var sExpirationDate = "expires=" + dExpirationDate.toUTCString();
document.cookie = "cookieName=cookieValue; " + sExpirationDate;