Uno script Gulp per automatizzare la compilazione dei files Sass (scss)

Gulpjs

Gulp js è una libreria javascript che permette di automatizzare svariate tipologie di noiose procedure che gli sviluppatori normalmente fanno “a mano”.

Proprio in questa direzione ho deciso di scrivere un breve script gulp che consente di automatizzare la ricompilazione dei fogli di stile SASS (scss), per evitarmi di lanciare, ad ogni modifica dei files, il comando sass sorgente.scss destinazione.css.

L’unico prerequisito per utilizzare gulp è di aver installato Nodejs ed il suo package manager npm (che viene installato di default insieme a node). Una volta installato node e scaricati i sorgenti del mio script basterà lanciare:

sudo npm install

…ed npm installerà per voi tutte le dipendenze necessarie!

Lo script prevede due modalità di esecuzione tramite i seguenti comandi:

  • gulp: compila i vostri scss presenti nella sottocartella src in un unico css nella root directory minifizzato (sass –style compressed)
  • gulp dev: compila gli scss in modalità espansa (sass –style expanded)

Questi due comandi avviano un task che rimane “in ascolto” e ad ogni modifica di un file scss rilancia il comando evitando il noioso compito di lanciare ogni volta la compilazione dei files per vedere le modifiche allo stile delle vostre web app/siti. In questo modo potrete scrivere le direttive di stile come si faceva prima dell’avvento di SASS/LESS e vedere immediatamente le nuove modifiche “live”.

Ho previsto un repository github “gulp-for-sass” con questo mini-progetto, scaricabile e modificabile liberamente!

Django + Supervisor su Ubuntu server

Supervisor, Django e Gunicorn

Continuando ad interessarmi al mondo Django sono venuto a conoscenza di un interessante sistema da utilizzare nello stack per il deploy di un’app sviluppata con questo framework.

Sto parlando di Supervisor, un sistema client/server per il controllo di processi Unix. Inizialmente nel mio stack avevo utilizzato Upstart, il controllore di processi presente di default su Ubuntu, ma utilizzando la funzione respawn, ossia per ogni processo terminato ne viene lanciato un altro, il sistema si perde il riferimento con il processo lanciato e i comandi di stop non hanno più effetto. Sentendo parlare bene di Supervisor mi sono deciso a provarlo ed effettivamente funziona alla grande!!! E’ possibile conoscere lo stato di tutti i processi registrati in Supervisor oltre ai classici comandi di start, stop e restart dei vari processi attivi.

Supervisor è presente all’interno del repository dei pacchetti Ubuntu, quindi per installarlo è sufficiente il comando:

sudo apt-get install supervisor

Per il primo avvio è necessario digitare:

service supervisor restart

A questo punto possiamo aggiure un nuovo programma, che nel caso di applicazioni Django sarà lo script python per l’avvio di Gunicorn (il server wsgi per Django di cui ho già ampiamente parlato qui), vediamo un esempio:

command = '/opt/APP_VIRTUAL_ENV/bin/gunicorn'
pythonpath = '/SRC/APP/PATH/'
bind = '127.0.0.1:8000'
workers = 3
user = 'CUSTOM_USER'
pid = '/var/run/APP_NAME.pid'
accesslog = '/var/log/gunicorn/APP_NAME/access.log'
errorlog = '/var/log/gunicorn/APP_NAME/error.log'

Ovviamente questo è un mio esempio di script per il lancio di gunicorn relativo ad una app django, ma questo tipo di configurazione è valido per qualsiasi processo che si vuole controllare, basta specificare all’interno di “command” il comando che supervisor deve lanciare e controllare. Io sono solito mettere questo script in una cartella chiamata appunto “script” allo stesso livello dei sorgenti dell’app, ma può essere posizionato in qualunque punto del sistema. Sarà poi il file di configurazione del programma in supervisor a dover sapere dove recuperare lo script appena preparato.

Come dicevo, supervisor viene informato di un comando da lanciare mediante un file (un file per ogni comando) all’interno della cartella /etc/supervisor/conf.d/APP.conf contenente le seguenti linee:

[program:APP_NAME]
command=/opt/APP_VIRTUAL_ENV/bin/gunicorn APP_NAME.wsgi:application -c/SRC/APP/SCRIPT/PATH/gunicorn_config.py
autostart=true
autorestart=true
stderr_logfile=/var/log/gunicorn/APP_NAME/supervisor_stderr.log
stdout_logfile=/var/log/gunicorn/APP_NAME/supervisor_stdout.log

Non sto a spiegare nel dettaglio il significato della prima linea, che è il comando per avviare Gunicorn con la nostra app django tramite lo script precedentemente scritto, mentre la seconda e la terza linea dicono a Supervisor rispettivamente di avviare il comando all’avvio del sistema e di riavviare i processi che vengono terminati in modo non naturale. Le ultime due linee specificano i percorsi dei files di log di Supervisor.

A questo punto dobbiamo dire a Supervisor di leggere la nuova configurazione:

supervisorctl reread

Seguito dal comando per abilitare il nuovo programma:

supervisorctl update

Adesso la nostra app dovrebbe essere avviata!

Potete controllare lo stato di Supervisor con il semplice comando:

supervisorctl status

Per avviare, stoppare o riavviare i processi sono presenti i comandi:

supervisorctl start
supervisorctl stop
supervisorctl restart

Mentre per avviare la console interattiva di Supervisor è sufficiente digitare:

supervisorctl

Non vi resta che scrivere app (Django, Node, ROR o ciò che più preferite) e farne controllare i loro processi da Supervisor!

Ng-Cookies e cookies su localhost con AngularJs

AngularJS-largeOggi scrivo di una piccola scoperta fatta giocando con AngularJs e i cookies che potrebbe tornare utile a chi di voi si deve cimentare nell’utilizzo di questa funzionalità javascript con l’ormai noto framework.

Facendo dei test di scrittura/lettura di informazioni all’interno dei cookies sembrava che non fosse consentito utilizzarli da localhost, ossia in locale. Più precisamente il cookie settato in una pagina, spariva letteralmente passando in un’altra pagina (cambiando url).

Dopo aver perso tutte le speranze e mentre vagavo senza meta all’interno delle issues del repository Github di AngularJs mi si è aperto un modo: un utente che si era interessato al problema dei cookies diceva che dopo averne discusso con il team di sviluppo aveva scoperto che per far funzionare a dovere questa funzionalità era necessario impostare il tag html base.

Facciamo un esempio: se il vostro progetto risponde all’url http://localhost/tests/angularjs/cookies sarà necessario impostare il base tag nel seguente modo:

 <base href="http://localhost/tests/angularjs/cookies/"> 

In questo modo i cookies verranno salvati per tutte le url che inizieranno per l’indirizzo specificato nel tag.

Il particolare importante da notare è lo slash finale. Senza quello nulla funzionerà.

Id alfanumerici per le chiavi primarie in django

 

Django web framework

Oggi torno sul blog per scrivere un breve tutorial riguardante il “mondo” Django.

Da buon appassionato di questo framework continuo nei miei esperimenti e in questo articolo spiegherò come modificare le chiavi primarie delle tabelle django da numero intero a stringa alfanumeriche sulla falsa riga degli uuid di PostgreSQL.

Il framework usa come default chiavi primarie di tipo integer che per ovvi limiti di architettura del tipo int possono essere grandi al massimo 32 bit. Con poche righe di codice vedremo come sostituire la chiave primaria con un valore generato tramite il modulo python uuid.

Per prima cosa in genere mi creo un file utils.py nell’app principale, un modulo in cui inserire tutte le funzioni di utilità per l’app. All’interno di questo file andremo a creare la nostra funzione che genererà gli uuid in questo modo:


import uuid

def make_uuid():
   return str(uuid.uuid1())

In questo modo genereremo un id alfanumerico basato sul mac address dell’host da cui viene generato, un numero di sequenza (in questo caso random) e il timestamp corrente. In questo modo non solo avremo id univoci all’interno della tabella, ma addirittura all’interno dell’intero database azzerando di fatto la possibilità di collisioni (l’unica possibilità sarebbe se venissero generati nello stesso istante due id con lo stesso numero di sequenza, non impossibile ma altamente improbabile).

Una volta scritta questa funzione non ci resta che usarla per generare gli id all’interno dei nostri model come nell’esempio sottostante:

from APP_NAME.utils import make_uuid
from django.db import models

class MyModel(models.Model):
   id = models.CharField(max_length = 36, primary_key = True, default = make_uuid, editable = False)
   ... altri campi ...

Come potete vedere si dovrà importare la funzione appena scritta all’interno del file models.py e utilizzarla per specificare il valore di default del campo id (omesso di default in caso di id standard).

Se si volesse evitare di usare il mac address della macchina per generare l’uuid si potrebbe utilizzare una funzione differente. Ad esempio la uuid.uuid4() genera uuid random, ovviamente a discapito di una, seppure remota, possibilità di collisioni.

Template WordPress responsive per il mio blog!

responsive

Come avrete potuto sicuramente notare in questi ultimi giorni, ho finalmente pubblicato la nuova versione del template per il mio blog personale! Siamo arrivati alla versione 4!

Ho deciso di sviluppare un tema WordPress totalmente nuovo, partendo da un foglio bianco ed ispirandomi a “cose” viste qua e là.

La mia esigenza era quella di ottenere, con il minimo sforzo, un template ottimizzato per tutti i dispositivi, da quelli con schermi ad alta risoluzione fino ai “mobile”, sempre più in voga negli ultimi tempi. Ho perciò utilizzato lo standard de facto dei framework CSS: Bootstrap 3! Ed ecco il risultato, un template adatto a desktop, tablet e smartphone!

Mi sono servito di una classe walker scritta ad hoc per utilizzare i menu WordPress con Boostrap, in modo da poter sfruttare la navbar fissata in alto. Per il resto la giusta miscela di codice php e html, qualche file css/js ed ecco qua, il nuovo template!

Il font che ho scelto è l’Open Sans, uno dei più utilizzati ultimamente sul web, e mi viene servito direttamente da Google Fonts.

Spero di essere riuscito nell’intento di fornire una navigazione più piacevole e al tempo stesso più completa. Presto cercherò di rendere disponibile gratuitamente e sotto licenza open source questo tema nel repository di WordPress. Nel frattempo se avete domande/curiosità non esitate a commentare l’articolo o a scrivermi tramite la solita pagina dei contatti.

Invece il prossimo passo che ho in mente per il blog sarà qualche cambiamento “sotto il cofano”, ma non voglio svelarvi niente e mi tengo un po’ di tempo per fare ancora qualche test!

A presto!

Evitare il caching del css di WordPress

wordpress_logo

In questo brevissimo articolo vi dimostrerò come evitare che il browser degli utenti usi una versione non aggiornata del vostro css di WordPress.

Con questa breve funzione andremo ad inserire un parametro in fondo al richiamo del foglio di stile che inserisca il timestamp dell’ultima modifica del file, in modo che la cache continui a funzionare fino a quando non sarete voi a modificare il file.

<link href="<?php echo get_bloginfo('template_url'); ?>/style.css?v=<?php echo filemtime(get_stylesheet_directory().'/style.css'); ?>" rel="stylesheet" media="screen">

Come potete vedere abbiamo applicato il concetto al css principale di wordpress ma si può applicare a qualsiasi file css, js o di immagini. La funzione di php utilizzata è la filemtime.

Aggirare le limitazioni delle API di Google Maps per il calcolo dei percorsi

Google Maps API

Torno a scrivere sul mio blog per trattare un argomento a mio giudizio interessante, anche se un po’ specifico.
Per conto di un cliente mi sto occupando delle API di Google Maps, in particolare l’ultima versione, ossia la V3.
Premetto, per chi non conoscesse l’argomento, che dalla versione 2 c’è stato un grande passo avanti, con ottime nuove funzionalità e tanti metodi che fanno risparmiare un sacco di tempo… D’altronde stiamo parlando di Big G!

Lo script che pubblico in questa pagina serve per rimediare al problema delle limitazioni poste da Google su ogni singola richiesta di calcolo di un percorso. Il cliente in questione deve visualizzare sulla mappa il tragitto tra due punti, passando però per un numero indefinito di punti intermedi.

Per fare questo Google rende disponibili le directions API impostando però il limite di 2500 richieste giornaliere e 8 punti intermedi per richiesta. L’idea è semplice, ottimizzare le richieste includendo al massimo 8 punti intermedi, settando però, dalla seconda richiesta in avanti, il punto di partenza uguale al punto finale della richiesta precedente.

Vediamo il codice javascript:

    var map = null;
    var markers = new Array();
    var coordinates = new Array();
    var directionsDisplay = new Array();
    var directionsService = new google.maps.DirectionsService();
    function placeMarker(lat, lng){
        var markerPos = new google.maps.LatLng(lat, lng);
        var marker = new google.maps.Marker({
            position: markerPos,
            map: map,
            draggable: true,
            animation: google.maps.Animation.DROP
        });
        markers.push(marker);
    }

    function removeRoutes(){
        for(var i = 0; i &lt; directionsDisplay.length; i++){
            directionsDisplay[i].setMap(null);
        }
        directionsDisplay = new Array();
    }

    function drawRoute(begin, end, waypts){
        var request = {
            origin: begin,
            destination: end,
            waypoints: waypts,
            optimizeWaypoints: true,
            travelMode: google.maps.TravelMode.DRIVING
        };
        directionsService.route(request, function(response, status) {
            if (status === google.maps.DirectionsStatus.OK) {
                var dirDisp = new google.maps.DirectionsRenderer({suppressMarkers: true});
                dirDisp.setMap(map);
                dirDisp.setDirections(response);
                directionsDisplay.push(dirDisp);
            }
        });
    }

    function calculateRoutes(){
        removeRoutes();
        var begin = new google.maps.LatLng(coordinates[0][0], coordinates[0][1]);
        var end = null;
        var waypts = new Array();
        var wCount = 0;
        var REQUEST_WAYPOINTS_LIMIT = 8;
        var i;
        for(i = 1; i &lt; (coordinates.length-1); i++){
            if(wCount === REQUEST_WAYPOINTS_LIMIT){
                i++;
                end = new google.maps.LatLng(coordinates[i][0], coordinates[i][1]);
                drawRoute(begin, end, waypts);
                begin = end;
                wCount = 0;
                waypts = new Array();
            }
            waypts.push({
                location: new google.maps.LatLng(coordinates[i][0], coordinates[i][1]),
                stopover: true
            });
            wCount++;
        }
        if(waypts.length &gt; 0){
            end = new google.maps.LatLng(coordinates[coordinates.length-1][0], coordinates[coordinates.length-1][1]);
            drawRoute(begin, end, waypts);
        }
        for(var i = 0; i &lt; coordinates.length; i++){
            placeMarker(coordinates[i][0], coordinates[i][1]);
        }
    }

Nel codice qui sopra come potete vedere ho un array di coordinate che contiene i vari punti da rappresentare sulla mappa, e il percorso deve essere calcolato partendo dalla prima coordinata presente in array per arrivare all’ultima cella dell’array, passando per tutte le altre.

Ho dato per scontato che la mappa sia già stata inizializzata e che la variabile map contenga l’oggetto google.maps.Map.

Un’ulteriore miglioria già fatta (che tratterò in un futuro articolo) sarà quella di colorare e numerare i marker dinamicamente e di adattare automaticamente lo zoom della mappa ai markers attivi sulla mappa visualizzata.

Visualizzare ed eliminare foreign keys in MySQL

MySQL

Con l’avvento di InnoDB su MySQLci si trova sempre più spesso a dover trattare tabelle con chiavi esterne. A volte per modificare una tabella si rende indispensabile eliminare le chiavi prima di eseguire la modifica, chiavi che però non sono elencate insieme alla struttura della tabella. Per estrarre quindi la lista delle chiavi di una tabella la query da eseguire è quindi la seguente:

select * from KEY_COLUMN_USAGE WHERE TABLE_SCHEMA = '<em>database_name</em>' AND TABLE_NAME = '<em>table_name</em>'

Come si può intuire, al posto di database_name si dovrà inserire il nome del database in cui risiede la tabella, e al posto di table_namesi dovrà scrivere il nome della tabella dalla quale estrarre le chiavi.
Una volta ottenuta la lista di foreign key, per elimare una chiave il codice sql da eseguire è:

ALTER TABLE <em>table_name</em> DROP FOREIGN KEY <em>foreign_key_name</em>

Table_name è come sopra il nome della tabella in cui risiedono le chiavi esterne, mentre foreign_key_name è il nome della chiave ottenuto dalla lista estratta con la query precedente.

Eseguire chiamate AJAX con jQuery e JSON in WordPress

Ajax and WordPress

Succede sempre più di frequente di dover effettuare delle chiamate ajax in WordPress. In questo articolo vedremo come effettuare delle chiamate asincrone senza dover creare nuove pagine WordPress ma sfruttando lo script utilizzato dall’interfaccia del wp-admin.
Nell’esempio in questione, la chiamata AJAX restituirà un file JSON formato davvero utile per rappresentare i dati restituiti da una query. Lato javascript useremo la funzione $.getJSON(…) di jQuery mentre lato server scriveremo il nostro script all’interno del file functions.php presente in qualsiasi tema WordPress.

Per prima cosa dobbiamo creare la corrispondenza tra una nuova action e la nostra funzione php:

add_action('wp_ajax_myaction', 'my_function');

Fatto ciò possiamo scrivere la nostra funzione my_function la quale corrisponderà all’azione myaction (il nome è puramente indicativo, potete chiamare l’azione e la funzione come preferite):

function my_function() {
  global $wpdb;
  $id = $_GET['id'];
  $rows = array();
  $q = "SELECT * FROM my_table WHERE id = ".$id;
  $rows['results'] = $wpdb->get_results($q, ARRAY_A);
  if(count($rows) <= 0){
    return false;
  }
  echo json_encode($rows);
  exit();
}

In questo script trovate tutto l’indispensabile per completare la parte lato server. Come si può intuire la query dovrà utilizzare un parametro passato in GET, poi utilizzando la variabile globale wpdb effettueremo la query sul database. La json_encode trasformerà l’array associativo con i record letti tramite la SELECT in una stringa JSON e la stamperemo a video tramite l’echo. Non dimenticate la exit() finale perchè altrimenti verrà stampato uno “0” che vi metterà in difficoltà nel parsificare il JSON.

Un ultimo particolare di cui tenere conto è che la add_action crea un’azione per l’admin-ajax.php che è un file accessibile solo da utenti loggati, quindi per consentire l’esecuzione dell’azione sia da utenti registrati sia da ospiti sarà necessario aggiungere un’ulteriore linea di codice come questa:

add_action('wp_ajax_nopriv_myaction', 'my_function');

Dopo aver completato lo script PHP possiamo passare al lato client, con il codice javascript per la chiamata della funzione:

$jQ.getJSON('<?php echo get_bloginfo('url'); ?>/wp-admin/admin-ajax.php',{action: 'myaction',id: 'tuo_id'}, function(json){...Codice javascript per parsificare il json...}

Ho omesso l’inclusione di jquery in WordPress, ma potete trovare come fare in un mio precedente articolo che trattava l’argomento nello specifico.

A questo punto non vi resta che sbizzarrirvi con le chiamate ajax nel vostro template oppure dai vostri plugin (in quest’ultimo caso basta spostare il codice PHP in un file del vostro plugin).

Piccoli traguardi… piccole soddisfazioni, 2000 visite mensili!

Report Google Analytics

Cari lettori del blog, oggi ho raggiunto un piccolo ma importante traguardo… I dati di google analytics parlano chiaro, sono state sorpassate le 2000 visite mensili e per questo voglio condividere con voi alcune statistiche di cui vado fiero.

Dal 27 agosto al 26 settembre questo blog ha ricevuto 2004 visite, con 1672 visitatori unici e 2369 visualizzazioni di pagina di cui 2175 uniche. L’80,84% delle visite sono nuove e ovviamente il paese predominante è l’italia con 1910 visite  delle quali 1853 in lingua italiana.

I tre articoli più popolari per il momento sono nell’ordine “Creare un web service con soap e php” con 401 visualizzazioni, “Sincronizzare Google Calendar con iCal su Mac e iPhone” con 395 visualizzazioni e “Calibrare la batteria di un Macbook Pro e non solo…” con 323 visualizzazioni.

Grazie a tutti voi che mi leggete, continuate a farlo! Mi auguro di poter continuare a scrivere articoli (spero) interessanti per accrescere questi numeri!

A presto, Davide.