<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Davide Ferrero</title>
	<atom:link href="https://blog.davideferrero.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.davideferrero.com</link>
	<description>Web developer for passion</description>
	<lastBuildDate>Mon, 01 Nov 2021 13:11:01 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.7.5</generator>
	<item>
		<title>Stubbing MQTT.js library in Ember.js tests with Sinon.JS</title>
		<link>https://blog.davideferrero.com/2021/11/stubbing-mqtt-js-library-in-ember-js-tests-with-sinon-js/</link>
					<comments>https://blog.davideferrero.com/2021/11/stubbing-mqtt-js-library-in-ember-js-tests-with-sinon-js/#respond</comments>
		
		<dc:creator><![CDATA[davide]]></dc:creator>
		<pubDate>Mon, 01 Nov 2021 08:30:00 +0000</pubDate>
				<category><![CDATA[Ember.js]]></category>
		<category><![CDATA[HowTo]]></category>
		<category><![CDATA[Informatica]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Ember Octane]]></category>
		<category><![CDATA[MQTT]]></category>
		<category><![CDATA[MQTT.js]]></category>
		<category><![CDATA[Sinon.JS]]></category>
		<guid isPermaLink="false">https://blog.davideferrero.com/?p=899</guid>

					<description><![CDATA[<p>I took the opportunity to upgrade the ember-mqttjs support to Ember v4 for refactoring the addons tests. During last EmberFest (which happened in Rome on Sept. 30 and Oct. 1, 2021) I listened to a lot of brilliant talks. One of them caught my attention because it dealt with the testing topic and in particular [&#8230;]</p>
<p>The post <a href="https://blog.davideferrero.com/2021/11/stubbing-mqtt-js-library-in-ember-js-tests-with-sinon-js/">Stubbing MQTT.js library in Ember.js tests with Sinon.JS</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></description>
										<content:encoded><![CDATA[<div class="wp-block-image"><figure class="aligncenter size-full"><img fetchpriority="high" decoding="async" width="254" height="252" src="https://blog.davideferrero.com/wp-content/uploads/2021/11/sinonjs.png" alt="Sinon.JS" class="wp-image-900" srcset="https://blog.davideferrero.com/wp-content/uploads/2021/11/sinonjs.png 254w, https://blog.davideferrero.com/wp-content/uploads/2021/11/sinonjs-150x150.png 150w" sizes="(max-width: 254px) 100vw, 254px" /></figure></div>



<p>I took the opportunity to upgrade the <a href="https://github.com/domoticalabs/ember-mqttjs" title="ember-mqttjs">ember-mqttjs</a> support to <a href="https://emberjs.com/releases/" title="Ember.js releases">Ember v4</a> for refactoring the addons tests. During last <a href="https://emberfest.eu/" title="EmberFest 2021">EmberFest</a> (which happened in Rome on Sept. 30 and Oct. 1, 2021) I listened to a lot of brilliant talks. One of them caught my attention because it dealt with the testing topic and in particular of mocks and stubs.</p>



<p><a title="Gonçalo Morais twitter account's" href="https://twitter.com/gnclmorais">Gonçalo Morais</a> dove into this argument with some stunning hints during his talk <a href="https://emberfest.eu/schedule/#goncalo-morais">&#8220;Mock &amp; Roll&#8221;</a> that opened my minds and let me wondering on how to improve my mqtt ember addon tests.</p>



<p>After some experiments with the mock-socket library I realized that this tool was not anymore mantained and combining some searchs into the <a href="https://sinonjs.org/" title="Sinon.JS javascript library">Sinon.JS</a> documentation I found a way to <a href="https://sinonjs.org/how-to/stub-dependency/" title="Sinon.JS stub dependency how-to">stub the MQTT.js dependency</a> faking the connect method.</p>



<p>This method returns a client and triggers some events that are useful to understand the mqtt connection status. Joining the replace and fake methods from Sinon.JS I found a way to simulate the MQTT.js connect method behavior returning a client with the necessary methods and triggering the needed events.</p>



<p>As you can see next on the code sample attached to this post I need to add some tricks to the joke, because for example the <em>connect</em> event needs to be trigger after a delay while the fake client declares an event handler that must to be there when the event is fired. Or for example the subscribe and publish methods need to call a callback with the correct parameters.</p>



<p>Once I discovered this tricks the tests runs correctly and I can assume that my code is working fine relying on the MQTT.js client to be properly tested.</p>



<h2 class="wp-block-heading">Code sample</h2>



<p>This is the example for the connect test but you can find the whole code into the <a href="https://github.com/domoticalabs/ember-mqttjs/blob/master/tests/unit/services/mqtt-test.js">addon repository</a>:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import sinon from 'sinon';
import mqttjs from 'mqtt/dist/mqtt';
import Service from '@ember/service';
import Evented from '@ember/object/evented';
import { later } from '@ember/runloop';

class MqttServiceStub extends Service.extend(Evented) {}

module('Unit | Service | mqtt', function (hooks) {
  let mqttHost = 'ws://localhost:8883';
  let mqttTopic = 'presence';
  let mqttMessage = 'Hello';

  let mqttServiceStub;

  setupTest(hooks);

  hooks.afterEach(() =&gt; {
    sinon.restore();
  });

  // ...

  //Testing mqtt connect
  test('mqtt connect success', async function (assert) {
    let service = this.owner.lookup('service:mqtt');
    let done = assert.async();
    assert.expect(3);
    mqttServiceStub = new MqttServiceStub();
    sinon.replace(
      mqttjs,
      'connect',
      sinon.fake(() =&gt; {
        later(() =&gt; {
          mqttServiceStub.trigger('connect');
        }, 100);
        return {
          on: (sEvent) =&gt; {
            mqttServiceStub.on(sEvent, () =&gt; {
              if (sEvent === 'connect') {
                return service.onConnect();
              }
            });
          },
        };
      })
    );
    try {
      service.on('mqtt-connected', () =&gt; {
        assert.ok(true);
      });
      await service.connect(mqttHost);
      assert.ok(service);
      assert.ok(service.isConnected);
    } catch {
      assert.ok(false);
      assert.ok(false);
      assert.ok(false);
    } finally {
      done();
    }
  });
</pre></div>


<p>If you notice some errors or you need more informations about the code I&#8217;m happy to hear from you. Reach me through my <a href="https://blog.davideferrero.com/contacts/" title="Contact me">contact page</a>.</p><p>The post <a href="https://blog.davideferrero.com/2021/11/stubbing-mqtt-js-library-in-ember-js-tests-with-sinon-js/">Stubbing MQTT.js library in Ember.js tests with Sinon.JS</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://blog.davideferrero.com/2021/11/stubbing-mqtt-js-library-in-ember-js-tests-with-sinon-js/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>MQTT in Ember.js</title>
		<link>https://blog.davideferrero.com/2021/07/mqtt-in-ember/</link>
					<comments>https://blog.davideferrero.com/2021/07/mqtt-in-ember/#respond</comments>
		
		<dc:creator><![CDATA[davide]]></dc:creator>
		<pubDate>Sat, 10 Jul 2021 14:14:18 +0000</pubDate>
				<category><![CDATA[Ember.js]]></category>
		<category><![CDATA[HowTo]]></category>
		<category><![CDATA[Informatica]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[How-to]]></category>
		<category><![CDATA[MQTT]]></category>
		<category><![CDATA[MQTT.js]]></category>
		<category><![CDATA[Octane]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Web development]]></category>
		<guid isPermaLink="false">https://blog.davideferrero.com/?p=872</guid>

					<description><![CDATA[<p>How to connect an Ember Octane app to an MQTT broker through the mqtt.js client library using the ember-mqttjs addon. Supports secure websocket/mqtt connection.</p>
<p>The post <a href="https://blog.davideferrero.com/2021/07/mqtt-in-ember/">MQTT in Ember.js</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></description>
										<content:encoded><![CDATA[<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><img decoding="async" src="https://blog.davideferrero.com/wp-content/uploads/2021/07/octane_mqttjs-573x600.png" alt="Ember Octane mqtt.js" class="wp-image-873" width="363" height="380" srcset="https://blog.davideferrero.com/wp-content/uploads/2021/07/octane_mqttjs-573x600.png 573w, https://blog.davideferrero.com/wp-content/uploads/2021/07/octane_mqttjs-286x300.png 286w, https://blog.davideferrero.com/wp-content/uploads/2021/07/octane_mqttjs-768x804.png 768w, https://blog.davideferrero.com/wp-content/uploads/2021/07/octane_mqttjs.png 800w" sizes="(max-width: 363px) 100vw, 363px" /></figure></div>



<p>Less than 2 years ago I started a new project with the company I work for that requires to an <a href="https://emberjs.com/editions/octane/" target="_blank" rel="noreferrer noopener" title="Ember.js Octane edition">Ember Octane</a> app to control several connected IoT devices around the world. We choosed the <a href="https://en.wikipedia.org/wiki/MQTT" target="_blank" rel="noreferrer noopener" title="MQTT on Wikipedia">MQTT</a> publish/subscribe network protocol to interact with our on-field devices for its lightweight message structure and its limited network bandwith requirements.</p>



<p>After googling for a javascript MQTT library I’ve found the <a href="https://github.com/mqttjs/MQTT.js" target="_blank" rel="noreferrer noopener" title="MQTT.js">MQTT.js</a> client. At the moment of my search the <a href="https://github.com/mqttjs/async-mqtt" target="_blank" rel="noreferrer noopener" title="Async MQTT.js">asynchronous version </a>was not yet released, so I had to wrap the event based client into an Ember service and transform it into a Promise based client.</p>



<p>This is a mandatory requirement because I need broker connection before subscribing to a topic or I need topic subscription before publishing on it. Sometimes you had retain messages on a topic for receiving last published value after the subscription. Other times you need publishing an empty value on a topic to request the status of a given device. So you need working subscribtion on a topic before sending a message. That said javascript <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise" target="_blank" rel="noreferrer noopener" title="Javascript Promise">Promises</a> are the only way to accomplish this tasks.</p>



<p>When I wrote this service I didn&#8217;t find an Ember addon ready to do this things. Therefore I decided to dive into the <a href="https://cli.emberjs.com/release/writing-addons/intro-tutorial/" target="_blank" rel="noreferrer noopener" title="Writing your first Ember.js addon">docs</a> and learn how to build an addon. The <a href="https://github.com/domoticalabs/ember-mqttjs" target="_blank" rel="noreferrer noopener" title="ember-mqttjs GitHub page">ember-mqttjs</a> addon is my first Ember addon!</p>



<h2 class="wp-block-heading">The code</h2>



<p>This service extends the <a href="https://api.emberjs.com/ember/release/classes/Evented" target="_blank" rel="noreferrer noopener" title="Evented Ember object">Evented</a> Ember object for raising events on new messages as well as connect, disconnect events and many others you can find on its <a href="https://github.com/domoticalabs/ember-mqttjs/blob/master/README.md" target="_blank" rel="noreferrer noopener" title="Readme for ember-mqttjs">readme</a>. In addition of raising this events it returns a Promise for connect, subscribe, unsubscribe and publish methods.</p>



<p>This is an example of another service that uses the ember-mqttjs service:</p>

<pre class="brush: jscript; title: ; notranslate">
import Service, { inject as service } from '@ember/service';
import { bind } from '@ember/runloop';

export default class YourService extends Service {
  @service mqtt;
  constructor() {
    super(...arguments);
    //...
    let _fOnMessage = bind(this, this._onMessage);
    this.mqtt.on('mqtt-message', _fOnMessage); 
  }

  _onMessage(sTopic, sMessage) {
    //code to manage messages received on a certain topic
  }

  async subscribeAndPublish(sTopic, sMessage) {
    try {
      await this.mqtt.connect(HOST, USERNAME, PASSWORD)
    } catch (oError) {
      //code on connection error
    }
    try {
      await this.mqtt.subscribe(sTopic);
    } catch (oError) {
      //code for subscription error
    }
    try {
      await this.mqtt.publish(sTopic, sMessage);
    } catch (oError) {
      //code for message publish error
    }
    return Promise.resolve();
  }
//...
}
</pre>



<p>I&#8217;ve just refactored the addon code to use async/await features and I moved the <a href="https://en.wikipedia.org/wiki/Continuous_integration" target="_blank" rel="noreferrer noopener" title="Continuos integration on Wikipedia">CI</a> from travis to github action (thanks to this Jeldrik Haschke&#8217;s <a href="https://github.com/jelhan/create-github-actions-setup-for-ember-addon" target="_blank" rel="noreferrer noopener">repo</a>). <br />Many improvements can be done in the future starting from writing more tests to cover other cases.<br />If you have any suggestions or proposal to improve the code as well as the tests you are welcome!</p>



<p><a href="https://blog.davideferrero.com/contacts/" title="Contact me">Contact me</a> or start contributing on <a href="https://github.com/domoticalabs/ember-mqttjs" target="_blank" rel="noreferrer noopener" title="GitHub project repository">GitHub project repo</a>!</p><p>The post <a href="https://blog.davideferrero.com/2021/07/mqtt-in-ember/">MQTT in Ember.js</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://blog.davideferrero.com/2021/07/mqtt-in-ember/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Ember + Boostrap 5</title>
		<link>https://blog.davideferrero.com/2021/06/ember-boostrap-5/</link>
					<comments>https://blog.davideferrero.com/2021/06/ember-boostrap-5/#respond</comments>
		
		<dc:creator><![CDATA[davide]]></dc:creator>
		<pubDate>Thu, 24 Jun 2021 22:26:53 +0000</pubDate>
				<category><![CDATA[Bootstrap]]></category>
		<category><![CDATA[Ember.js]]></category>
		<category><![CDATA[HowTo]]></category>
		<category><![CDATA[Informatica]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Boostrap5]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Ember Octane]]></category>
		<category><![CDATA[Sass]]></category>
		<category><![CDATA[Scss]]></category>
		<guid isPermaLink="false">https://blog.davideferrero.com/?p=858</guid>

					<description><![CDATA[<p>How to create an Ember.js app with Bootstrap 5.</p>
<p>The post <a href="https://blog.davideferrero.com/2021/06/ember-boostrap-5/">Ember + Boostrap 5</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></description>
										<content:encoded><![CDATA[<div class="wp-block-image"><figure class="aligncenter size-large"><img decoding="async" width="600" height="288" src="https://blog.davideferrero.com/wp-content/uploads/2021/06/ember-bootstrap5-600x288.jpg" alt="" class="wp-image-859" srcset="https://blog.davideferrero.com/wp-content/uploads/2021/06/ember-bootstrap5-600x288.jpg 600w, https://blog.davideferrero.com/wp-content/uploads/2021/06/ember-bootstrap5-300x144.jpg 300w, https://blog.davideferrero.com/wp-content/uploads/2021/06/ember-bootstrap5-768x368.jpg 768w, https://blog.davideferrero.com/wp-content/uploads/2021/06/ember-bootstrap5-1536x737.jpg 1536w, https://blog.davideferrero.com/wp-content/uploads/2021/06/ember-bootstrap5.jpg 1564w" sizes="(max-width: 600px) 100vw, 600px" /></figure></div>



<p>Today I welcome a new template for my <a href="https://blog.davideferrero.com" title="Davide Ferrero's blog">blog</a> by returning to write a post after a very long time!</p>



<p>This <a href="https://wordpress.org/" target="_blank" rel="noreferrer noopener" title="WordPress">WordPress</a> theme is built on top of the latest <a href="https://getbootstrap.com/" target="_blank" rel="noreferrer noopener" title="Bootstrap">Bootstrap</a> release, Bootstrap 5 and with this post I would like to explain you how to use this  hugely popular front-end framework in an <a href="https://emberjs.com/" target="_blank" rel="noreferrer noopener" title="Ember.js">Ember</a> app.</p>



<p>With this major new release the developers have focused most of their efforts towards removing <a href="https://jquery.com/" target="_blank" rel="noreferrer noopener" title="jQuery">jQuery</a> as a dependency of the framework to make it lighter and usable by a wider audience now interested in saving as much kb as possible.</p>



<p>For those who knows and uses the previous Bootstrap version (v4) I suggest to dive into the <a href="https://getbootstrap.com/docs/5.0/migration/" target="_blank" rel="noreferrer noopener" title="Bootstrap 5 migration guide">migration guide</a>, to understand what breaking changes were made in this new update.</p>



<p>As an experiment (I will tell you later about what I am working on in my spare time) I&#8217;ve tried to use Bootstrap 5 in a new Ember Octane app and thank to the release of the bootstrap npm package this turned out to be tremendously simple.</p>



<p>Let&#8217;s see the steps:</p>



<p>First you have to install the bootstrap npm package:<br /><pre class="brush: bash; title: ; notranslate">npm install --save-dev bootstrap</pre></p>



<p>Then you have to modify your <em>ember-cli-build.js</em> file:</p>



<p><pre class="brush: jscript; title: ; notranslate">'use strict';

const EmberApp = require('ember-cli/lib/broccoli/ember-app');

module.exports = function (defaults) {
  let app = new EmberApp(defaults, {
    // Add options here
    sassOptions: {
      includePaths: &#x5B;'node_modules/bootstrap/scss'],
    },
  });
  app.import('node_modules/bootstrap/dist/js/bootstrap.bundle.min.js');
  return app.toTree();
};
</pre></p>



<p>The last few steps are required to be able to import bootstrap SCSS files.<br />First you have to install <em><a href="https://github.com/adopted-ember-addons/ember-cli-sass" target="_blank" rel="noreferrer noopener" title="https://github.com/adopted-ember-addons/ember-cli-sass">ember-cli-sass</a></em> addon:</p>



<p><pre class="brush: bash; title: ; notranslate">ember install ember-cli-sass</pre></p>



<p>Then you have to rename your app style app.css to app.scss and insert the line to import the bootstrap files:</p>



<p><pre class="brush: css; title: ; notranslate">@import 'bootstrap';</pre></p>



<p>You are now ready to use Bootstrap 5 in your Ember app!</p><p>The post <a href="https://blog.davideferrero.com/2021/06/ember-boostrap-5/">Ember + Boostrap 5</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://blog.davideferrero.com/2021/06/ember-boostrap-5/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Uno script Gulp per automatizzare la compilazione dei files Sass (scss)</title>
		<link>https://blog.davideferrero.com/2016/05/script-gulp-per-automatizzare-la-compilazione-dei-files-sass-scss/</link>
					<comments>https://blog.davideferrero.com/2016/05/script-gulp-per-automatizzare-la-compilazione-dei-files-sass-scss/#respond</comments>
		
		<dc:creator><![CDATA[davide]]></dc:creator>
		<pubDate>Sun, 01 May 2016 13:15:03 +0000</pubDate>
				<category><![CDATA[HowTo]]></category>
		<category><![CDATA[Informatica]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Utility]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Gulp]]></category>
		<category><![CDATA[Gulpjs]]></category>
		<category><![CDATA[Nodejs]]></category>
		<category><![CDATA[Sass]]></category>
		<category><![CDATA[Scss]]></category>
		<guid isPermaLink="false">http://blog.davideferrero.com/?p=819</guid>

					<description><![CDATA[<p>Gulp js è una libreria javascript che permette di automatizzare svariate tipologie di noiose procedure che gli sviluppatori normalmente fanno &#8220;a mano&#8221;. 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 [&#8230;]</p>
<p>The post <a href="https://blog.davideferrero.com/2016/05/script-gulp-per-automatizzare-la-compilazione-dei-files-sass-scss/">Uno script Gulp per automatizzare la compilazione dei files Sass (scss)</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-820" src="//blog.davideferrero.com/wp-content/uploads/2016/05/gulp-white-text.png" alt="Gulpjs" width="253" height="153" /></p>
<p><a href="http://gulpjs.com/" target="_blank" rel="noopener">Gulp js</a> è una libreria javascript che permette di automatizzare svariate tipologie di noiose procedure che gli sviluppatori normalmente fanno &#8220;a mano&#8221;.</p>
<p>Proprio in questa direzione ho deciso di scrivere un breve script gulp che consente di automatizzare la ricompilazione dei fogli di stile <a href="http://sass-lang.com/" target="_blank" rel="noopener">SASS</a> (scss), per evitarmi di lanciare, ad ogni modifica dei files, il comando <strong><em>sass</em> <em>sorgente.scss</em> <em>destinazione.css</em></strong>.</p>
<p>L&#8217;unico prerequisito per utilizzare gulp è di aver installato <a href="https://nodejs.org/en/" target="_blank" rel="noopener">Nodejs</a> 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:</p>
<pre class="brush: bash; title: ; notranslate">sudo npm install</pre>
<p>&#8230;ed npm installerà per voi tutte le dipendenze necessarie!</p>
<p>Lo script prevede due modalità di esecuzione tramite i seguenti comandi:</p>
<ul>
<li><strong><em>gulp</em></strong>: compila i vostri scss presenti nella sottocartella src in un unico css nella root directory minifizzato (<em>sass &#8211;style compressed</em>)</li>
<li><strong><em>gulp dev</em></strong>: compila gli scss in modalità espansa (<em>sass &#8211;style expanded</em>)</li>
</ul>
<p>Questi due comandi avviano un task che rimane &#8220;in ascolto&#8221; 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&#8217;avvento di SASS/<a href="http://lesscss.org/" target="_blank" rel="noopener">LESS</a> e vedere immediatamente le nuove modifiche &#8220;live&#8221;.</p>
<p>Ho previsto un repository <a href="https://github.com/davideferre/gulp-for-sass/" target="_blank" rel="noopener">github &#8220;gulp-for-sass&#8221;</a> con questo mini-progetto, scaricabile e modificabile liberamente!</p><p>The post <a href="https://blog.davideferrero.com/2016/05/script-gulp-per-automatizzare-la-compilazione-dei-files-sass-scss/">Uno script Gulp per automatizzare la compilazione dei files Sass (scss)</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://blog.davideferrero.com/2016/05/script-gulp-per-automatizzare-la-compilazione-dei-files-sass-scss/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Django + Supervisor su Ubuntu server</title>
		<link>https://blog.davideferrero.com/2015/10/django-supervisor-ubuntu-server/</link>
					<comments>https://blog.davideferrero.com/2015/10/django-supervisor-ubuntu-server/#respond</comments>
		
		<dc:creator><![CDATA[davide]]></dc:creator>
		<pubDate>Sat, 17 Oct 2015 14:21:05 +0000</pubDate>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[HowTo]]></category>
		<category><![CDATA[Informatica]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Gunicor]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Server]]></category>
		<category><![CDATA[Supervisor]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<guid isPermaLink="false">http://blog.davideferrero.com/?p=804</guid>

					<description><![CDATA[<p>Continuando ad interessarmi al mondo Django sono venuto a conoscenza di un interessante sistema da utilizzare nello stack per il deploy di un&#8217;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 [&#8230;]</p>
<p>The post <a href="https://blog.davideferrero.com/2015/10/django-supervisor-ubuntu-server/">Django + Supervisor su Ubuntu server</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" decoding="async" class="aligncenter wp-image-806 size-large" src="http://blog.davideferrero.com/wp-content/uploads/2015/10/localhost2-600x278.jpg" alt="Supervisor, Django e Gunicorn" width="600" height="278" srcset="https://blog.davideferrero.com/wp-content/uploads/2015/10/localhost2-600x278.jpg 600w, https://blog.davideferrero.com/wp-content/uploads/2015/10/localhost2-300x139.jpg 300w, https://blog.davideferrero.com/wp-content/uploads/2015/10/localhost2.jpg 806w" sizes="auto, (max-width: 600px) 100vw, 600px" /></p>
<p>Continuando ad interessarmi al mondo <a href="https://www.djangoproject.com/" target="_blank">Django</a> sono venuto a conoscenza di un interessante sistema da utilizzare nello stack per il deploy di un&#8217;app sviluppata con questo framework.</p>
<p>Sto parlando di <a href="http://supervisord.org/" target="_blank">Supervisor</a>, un sistema client/server per il controllo di processi Unix. Inizialmente nel mio stack avevo utilizzato <a href="http://upstart.ubuntu.com/" target="_blank">Upstart</a>, il controllore di processi presente di default su <a href="http://www.ubuntu.com/" target="_blank">Ubuntu</a>, ma utilizzando la funzione <em>respawn</em>, 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&#8217; possibile conoscere lo stato di tutti i processi registrati in Supervisor oltre ai classici comandi di <em>start</em>, <em>stop</em> e <em>restart</em> dei vari processi attivi.</p>
<p>Supervisor è presente all&#8217;interno del repository dei pacchetti Ubuntu, quindi per installarlo è sufficiente il comando:</p>
<pre class="brush: bash; title: ; notranslate">sudo apt-get install supervisor</pre>
<p>Per il primo avvio è necessario digitare:</p>
<pre class="brush: bash; title: ; notranslate">service supervisor restart</pre>
<p>A questo punto possiamo aggiure un nuovo programma, che nel caso di applicazioni Django sarà lo script python per l&#8217;avvio di <a href="http://gunicorn.org/" target="_blank">Gunicorn</a> (il server wsgi per Django di cui <a href="http://blog.davideferrero.com/2012/09/eseguire-unapplicazione-django-su-ubuntu-server-con-nginx-gunicorn-mysql-dung-stack/">ho già ampiamente parlato qui</a>), vediamo un esempio:</p>
<pre class="brush: python; title: ; notranslate">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'
</pre>
<p>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&#8217;interno di &#8220;command&#8221; il comando che supervisor deve lanciare e controllare. Io sono solito mettere questo script in una cartella chiamata appunto &#8220;script&#8221; allo stesso livello dei sorgenti dell&#8217;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.</p>
<p>Come dicevo, supervisor viene informato di un comando da lanciare mediante un file (un file per ogni comando) all&#8217;interno della cartella <em>/etc/supervisor/conf.d/APP.conf</em> contenente le seguenti linee:</p>
<pre class="brush: bash; title: ; notranslate">&#x5B;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</pre>
<p>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&#8217;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.</p>
<p>A questo punto dobbiamo dire a Supervisor di leggere la nuova configurazione:</p>
<pre class="brush: bash; title: ; notranslate">supervisorctl reread</pre>
<p>Seguito dal comando per abilitare il nuovo programma:</p>
<pre class="brush: bash; title: ; notranslate">supervisorctl update</pre>
<p>Adesso la nostra app dovrebbe essere avviata!</p>
<p>Potete controllare lo stato di Supervisor con il semplice comando:</p>
<pre class="brush: bash; title: ; notranslate">supervisorctl status</pre>
<p>Per avviare, stoppare o riavviare i processi sono presenti i comandi:</p>
<pre class="brush: bash; title: ; notranslate">supervisorctl start</pre>
<pre class="brush: bash; title: ; notranslate">supervisorctl stop</pre>
<pre class="brush: bash; title: ; notranslate">supervisorctl restart</pre>
<p>Mentre per avviare la console interattiva di Supervisor è sufficiente digitare:</p>
<pre class="brush: bash; title: ; notranslate">supervisorctl</pre>
<p>Non vi resta che scrivere app (Django, Node, ROR o ciò che più preferite) e farne controllare i loro processi da Supervisor!</p><p>The post <a href="https://blog.davideferrero.com/2015/10/django-supervisor-ubuntu-server/">Django + Supervisor su Ubuntu server</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://blog.davideferrero.com/2015/10/django-supervisor-ubuntu-server/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Ng-Cookies e cookies su localhost con AngularJs</title>
		<link>https://blog.davideferrero.com/2015/02/ng-cookies-e-cookies-su-localhost-con-angularjs/</link>
					<comments>https://blog.davideferrero.com/2015/02/ng-cookies-e-cookies-su-localhost-con-angularjs/#respond</comments>
		
		<dc:creator><![CDATA[davide]]></dc:creator>
		<pubDate>Mon, 23 Feb 2015 20:04:22 +0000</pubDate>
				<category><![CDATA[AngularJs]]></category>
		<category><![CDATA[HowTo]]></category>
		<category><![CDATA[Informatica]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Cookies]]></category>
		<category><![CDATA[Ng-Cookies]]></category>
		<category><![CDATA[Web development]]></category>
		<guid isPermaLink="false">http://blog.davideferrero.com/?p=784</guid>

					<description><![CDATA[<p>Oggi scrivo di una piccola scoperta fatta giocando con AngularJs e i cookies che potrebbe tornare utile a chi di voi si deve cimentare nell&#8217;utilizzo di questa funzionalità javascript con l&#8217;ormai noto framework. Facendo dei test di scrittura/lettura di informazioni all&#8217;interno dei cookies sembrava che non fosse consentito utilizzarli da localhost, ossia in locale. Più precisamente il [&#8230;]</p>
<p>The post <a href="https://blog.davideferrero.com/2015/02/ng-cookies-e-cookies-su-localhost-con-angularjs/">Ng-Cookies e cookies su localhost con AngularJs</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-787" src="http://blog.davideferrero.com/wp-content/uploads/2015/02/AngularJS-large.png" alt="AngularJS-large" width="383" height="108" srcset="https://blog.davideferrero.com/wp-content/uploads/2015/02/AngularJS-large.png 383w, https://blog.davideferrero.com/wp-content/uploads/2015/02/AngularJS-large-300x85.png 300w" sizes="auto, (max-width: 383px) 100vw, 383px" />Oggi scrivo di una piccola scoperta fatta giocando con <a title="AngularJs" href="https://angularjs.org/" target="_blank">AngularJs</a> e i <a title="Cookie" href="http://it.wikipedia.org/wiki/Cookie" target="_blank">cookies</a> che potrebbe tornare utile a chi di voi si deve cimentare nell&#8217;utilizzo di questa funzionalità javascript con l&#8217;ormai noto framework.</p>
<p>Facendo dei test di scrittura/lettura di informazioni all&#8217;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&#8217;altra pagina (cambiando url).</p>
<p>Dopo aver perso tutte le speranze e mentre vagavo senza meta all&#8217;interno delle <a title="Issues per AngularJs" href="https://github.com/angular/angular.js/issues" target="_blank">issues del repository Github di AngularJs</a> 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 <em><a title="Html base tag" href="http://www.w3schools.com/tags/tag_base.asp" target="_blank">base</a>.</em></p>
<p>Facciamo un esempio: se il vostro progetto risponde all&#8217;url <em>http://localhost/tests/angularjs/cookies sarà necessario impostare il base tag nel seguente modo:</em></p>
<pre class="brush: xml; title: ; notranslate"> &lt;base href=&quot;http://localhost/tests/angularjs/cookies/&quot;&gt; </pre>
<p>In questo modo i cookies verranno salvati per tutte le url che inizieranno per l&#8217;indirizzo specificato nel tag.</p>
<p>Il particolare importante da notare è lo <em>slash</em> finale. Senza quello nulla funzionerà.</p><p>The post <a href="https://blog.davideferrero.com/2015/02/ng-cookies-e-cookies-su-localhost-con-angularjs/">Ng-Cookies e cookies su localhost con AngularJs</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://blog.davideferrero.com/2015/02/ng-cookies-e-cookies-su-localhost-con-angularjs/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Id alfanumerici per le chiavi primarie in django</title>
		<link>https://blog.davideferrero.com/2015/01/id-alfanumerici-per-le-chiavi-primarie-in-django/</link>
					<comments>https://blog.davideferrero.com/2015/01/id-alfanumerici-per-le-chiavi-primarie-in-django/#respond</comments>
		
		<dc:creator><![CDATA[davide]]></dc:creator>
		<pubDate>Wed, 21 Jan 2015 21:30:47 +0000</pubDate>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[HowTo]]></category>
		<category><![CDATA[Informatica]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Programmazione]]></category>
		<category><![CDATA[Web development]]></category>
		<guid isPermaLink="false">http://blog.davideferrero.com/?p=769</guid>

					<description><![CDATA[<p>&#160; Oggi torno sul blog per scrivere un breve tutorial riguardante il &#8220;mondo&#8221; 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 [&#8230;]</p>
<p>The post <a href="https://blog.davideferrero.com/2015/01/id-alfanumerici-per-le-chiavi-primarie-in-django/">Id alfanumerici per le chiavi primarie in django</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-medium wp-image-775" src="http://blog.davideferrero.com/wp-content/uploads/2015/01/django-logo-positive-300x105.png" alt="Django web framework" width="300" height="105" srcset="https://blog.davideferrero.com/wp-content/uploads/2015/01/django-logo-positive-300x105.png 300w, https://blog.davideferrero.com/wp-content/uploads/2015/01/django-logo-positive-600x209.png 600w, https://blog.davideferrero.com/wp-content/uploads/2015/01/django-logo-positive.png 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></p>
<p>Oggi torno sul blog per scrivere un breve tutorial riguardante il &#8220;mondo&#8221; <a title="Django web framework" href="https://www.djangoproject.com/" target="_blank">Django</a>.</p>
<p>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 <a title="Uuid PostgreSQL" href="http://www.postgresql.org/docs/8.3/static/datatype-uuid.html" target="_blank">uuid</a> di <a title="PostgreSQL" href="http://www.postgresql.org/" target="_blank">PostgreSQL</a>.</p>
<p>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 <a title="Modulo uuid python" href="https://docs.python.org/2/library/uuid.html" target="_blank">uuid</a>.</p>
<p>Per prima cosa in genere mi creo un file <em>utils.py</em> nell&#8217;app principale, un modulo in cui inserire tutte le funzioni di utilità per l&#8217;app. All&#8217;interno di questo file andremo a creare la nostra funzione che genererà gli uuid in questo modo:</p>
<pre class="brush: python; title: ; notranslate">

import uuid

def make_uuid():
   return str(uuid.uuid1())

</pre>
<p>In questo modo genereremo un id alfanumerico basato sul <a title="Indirizzo Mac definito da Wikipedia" href="http://it.wikipedia.org/wiki/Indirizzo_MAC">mac address</a> dell&#8217;host da cui viene generato, un numero di sequenza (in questo caso <em>random</em>) e il timestamp corrente. In questo modo non solo avremo id univoci all&#8217;interno della tabella, ma addirittura all&#8217;interno dell&#8217;intero database azzerando di fatto la possibilità di collisioni (l&#8217;unica possibilità sarebbe se venissero generati nello stesso istante due id con lo stesso numero di sequenza, non impossibile ma altamente improbabile).</p>
<p>Una volta scritta questa funzione non ci resta che usarla per generare gli id all&#8217;interno dei nostri model come nell&#8217;esempio sottostante:</p>
<pre class="brush: python; title: ; notranslate">
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 ...
</pre>
<p>Come potete vedere si dovrà importare la funzione appena scritta all&#8217;interno del file models.py e utilizzarla per specificare il valore di default del campo <em>id</em> (omesso di default in caso di <em>id standard</em>).</p>
<p>Se si volesse evitare di usare il mac address della macchina per generare l&#8217;uuid si potrebbe utilizzare una funzione differente. Ad esempio la uuid.uuid4() genera uuid <em>random</em>, ovviamente a discapito di una, seppure remota, possibilità di collisioni.</p><p>The post <a href="https://blog.davideferrero.com/2015/01/id-alfanumerici-per-le-chiavi-primarie-in-django/">Id alfanumerici per le chiavi primarie in django</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://blog.davideferrero.com/2015/01/id-alfanumerici-per-le-chiavi-primarie-in-django/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Template WordPress responsive per il mio blog!</title>
		<link>https://blog.davideferrero.com/2013/12/template-wordpress-responsive-per-il-mio-blog/</link>
					<comments>https://blog.davideferrero.com/2013/12/template-wordpress-responsive-per-il-mio-blog/#respond</comments>
		
		<dc:creator><![CDATA[davide]]></dc:creator>
		<pubDate>Thu, 05 Dec 2013 22:14:20 +0000</pubDate>
				<category><![CDATA[Informatica]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Wordpress]]></category>
		<category><![CDATA[Bootstrap]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[Responsive]]></category>
		<category><![CDATA[Template]]></category>
		<category><![CDATA[Theme]]></category>
		<category><![CDATA[Web development]]></category>
		<guid isPermaLink="false">http://blog.davideferrero.com/?p=712</guid>

					<description><![CDATA[<p>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 &#8220;cose&#8221; viste qua e là. La mia esigenza era quella di [&#8230;]</p>
<p>The post <a href="https://blog.davideferrero.com/2013/12/template-wordpress-responsive-per-il-mio-blog/">Template WordPress responsive per il mio blog!</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></description>
										<content:encoded><![CDATA[<p style="text-align: center;"><img loading="lazy" decoding="async" class="aligncenter size-medium wp-image-717" alt="responsive" src="http://blog.davideferrero.com/wp-content/uploads/2013/12/responsive-300x181.jpg" width="300" height="181" srcset="https://blog.davideferrero.com/wp-content/uploads/2013/12/responsive-300x181.jpg 300w, https://blog.davideferrero.com/wp-content/uploads/2013/12/responsive.jpg 646w" sizes="auto, (max-width: 300px) 100vw, 300px" /></p>
<p>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!</p>
<p>Ho deciso di sviluppare un tema <a title="Wordpress" href="http://wordpress.org/" target="_blank">WordPress</a> totalmente nuovo, partendo da un foglio bianco ed ispirandomi a &#8220;cose&#8221; viste qua e là.</p>
<p>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 <em>&#8220;mobile&#8221;</em>, sempre più in voga negli ultimi tempi. Ho perciò utilizzato lo standard <em>de facto</em> dei framework CSS: <a title="Bootstrap 3" href="http://getbootstrap.com/" target="_blank">Bootstrap 3</a>! Ed ecco il risultato, un template adatto a desktop, tablet e smartphone!</p>
<p>Mi sono servito di <a title="Wp-bootstrap-navwalker" href="https://github.com/twittem/wp-bootstrap-navwalker" target="_blank">una classe <em>walker </em></a>scritta ad hoc per utilizzare i menu WordPress con Boostrap, in modo da poter sfruttare la <a title="Bootstrap navbar" href="http://getbootstrap.com/components/#navbar" target="_blank">navbar</a> <a title="Bootstrap navbar fixed to top" href="http://getbootstrap.com/components/#navbar-fixed-top" target="_blank">fissata in alto</a>. Per il resto la giusta miscela di codice php e html, qualche file css/js ed ecco qua, il nuovo template!</p>
<p>Il font che ho scelto è l&#8217;<a title="Open Sans font" href="http://www.google.com/fonts/specimen/Open+Sans" target="_blank">Open Sans</a>, uno dei più utilizzati ultimamente sul web, e mi viene servito direttamente da <a title="Google Fonts" href="http://www.google.com/fonts" target="_blank">Google Fonts</a>.</p>
<p>Spero di essere riuscito nell&#8217;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&#8217;articolo o a scrivermi tramite la solita pagina dei <a title="Contatti" href="http://blog.davideferrero.com/contatti/">contatti</a>.</p>
<p>Invece il prossimo passo che ho in mente per il blog sarà qualche cambiamento &#8220;sotto il cofano&#8221;, ma non voglio svelarvi niente e mi tengo un po&#8217; di tempo per fare ancora qualche test!</p>
<p>A presto!</p><p>The post <a href="https://blog.davideferrero.com/2013/12/template-wordpress-responsive-per-il-mio-blog/">Template WordPress responsive per il mio blog!</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://blog.davideferrero.com/2013/12/template-wordpress-responsive-per-il-mio-blog/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Evitare il caching del css di WordPress</title>
		<link>https://blog.davideferrero.com/2013/10/evitare-il-caching-del-css-di-wordpress-con-filemtime-php/</link>
					<comments>https://blog.davideferrero.com/2013/10/evitare-il-caching-del-css-di-wordpress-con-filemtime-php/#respond</comments>
		
		<dc:creator><![CDATA[davide]]></dc:creator>
		<pubDate>Wed, 30 Oct 2013 15:21:43 +0000</pubDate>
				<category><![CDATA[HowTo]]></category>
		<category><![CDATA[Informatica]]></category>
		<category><![CDATA[Utility]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Wordpress]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[PHP]]></category>
		<guid isPermaLink="false">http://blog.davideferrero.com/?p=694</guid>

					<description><![CDATA[<p>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&#8217;ultima modifica del file, in modo che la cache continui a [&#8230;]</p>
<p>The post <a href="https://blog.davideferrero.com/2013/10/evitare-il-caching-del-css-di-wordpress-con-filemtime-php/">Evitare il caching del css di WordPress</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-725" alt="wordpress_logo" src="http://blog.davideferrero.com/wp-content/uploads/2013/10/wordpress_logo.png" width="499" height="310" srcset="https://blog.davideferrero.com/wp-content/uploads/2013/10/wordpress_logo.png 499w, https://blog.davideferrero.com/wp-content/uploads/2013/10/wordpress_logo-300x186.png 300w" sizes="auto, (max-width: 499px) 100vw, 499px" /></p>
<p>In questo brevissimo articolo vi dimostrerò come evitare che il browser degli utenti usi una versione non aggiornata del vostro css di <a title="Wordpress" href="http://it.wordpress.org/" target="_blank">WordPress</a>.</p>
<p>Con questa breve funzione andremo ad inserire un parametro in fondo al richiamo del foglio di stile che inserisca il timestamp dell&#8217;ultima modifica del file, in modo che la cache continui a funzionare fino a quando non sarete voi a modificare il file.</p>
<pre class="brush: xml; title: ; notranslate">&lt;link href=&quot;&lt;?php echo get_bloginfo('template_url'); ?&gt;/style.css?v=&lt;?php echo filemtime(get_stylesheet_directory().'/style.css'); ?&gt;&quot; rel=&quot;stylesheet&quot; media=&quot;screen&quot;&gt;</pre>
<p>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 <a title="Funzione PHP filemtime" href="http://php.net/manual/en/function.filemtime.php" target="_blank">filemtime</a>.</p><p>The post <a href="https://blog.davideferrero.com/2013/10/evitare-il-caching-del-css-di-wordpress-con-filemtime-php/">Evitare il caching del css di WordPress</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://blog.davideferrero.com/2013/10/evitare-il-caching-del-css-di-wordpress-con-filemtime-php/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Aggirare le limitazioni delle API di Google Maps per il calcolo dei percorsi</title>
		<link>https://blog.davideferrero.com/2013/10/aggirare-le-limitazioni-delle-api-di-google-maps-per-il-calcolo-dei-percorsi/</link>
					<comments>https://blog.davideferrero.com/2013/10/aggirare-le-limitazioni-delle-api-di-google-maps-per-il-calcolo-dei-percorsi/#comments</comments>
		
		<dc:creator><![CDATA[davide]]></dc:creator>
		<pubDate>Tue, 15 Oct 2013 19:53:11 +0000</pubDate>
				<category><![CDATA[Google]]></category>
		<category><![CDATA[Google Maps API]]></category>
		<category><![CDATA[HowTo]]></category>
		<category><![CDATA[Informatica]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Directions]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Maps]]></category>
		<guid isPermaLink="false">http://blog.davideferrero.com/?p=680</guid>

					<description><![CDATA[<p>Torno a scrivere sul mio blog per trattare un argomento a mio giudizio interessante, anche se un po&#8217; specifico. Per conto di un cliente mi sto occupando delle API di Google Maps, in particolare l&#8217;ultima versione, ossia la V3. Premetto, per chi non conoscesse l&#8217;argomento, che dalla versione 2 c&#8217;è stato un grande passo avanti, [&#8230;]</p>
<p>The post <a href="https://blog.davideferrero.com/2013/10/aggirare-le-limitazioni-delle-api-di-google-maps-per-il-calcolo-dei-percorsi/">Aggirare le limitazioni delle API di Google Maps per il calcolo dei percorsi</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-729" alt="Google Maps API" src="http://blog.davideferrero.com/wp-content/uploads/2013/10/051.jpg" width="320" height="291" srcset="https://blog.davideferrero.com/wp-content/uploads/2013/10/051.jpg 320w, https://blog.davideferrero.com/wp-content/uploads/2013/10/051-300x272.jpg 300w" sizes="auto, (max-width: 320px) 100vw, 320px" /></p>
<p>Torno a scrivere sul mio blog per trattare un argomento a mio giudizio interessante, anche se un po&#8217; specifico.<br />
Per conto di un cliente mi sto occupando delle <a title="Google Maps API V3" href="https://developers.google.com/maps/documentation/javascript/" target="_blank">API di Google Maps</a>, in particolare l&#8217;ultima versione, ossia la V3.<br />
Premetto, per chi non conoscesse l&#8217;argomento, che dalla versione 2 c&#8217;è stato un grande passo avanti, con ottime nuove funzionalità e tanti metodi che fanno risparmiare un sacco di tempo&#8230; D&#8217;altronde stiamo parlando di <em>Big G!</em></p>
<p>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.</p>
<p>Per fare questo Google rende disponibili le <a title="Directions API" href="https://developers.google.com/maps/documentation/javascript/directions" target="_blank">directions API</a> impostando però il <a title="Google Maps Directions API limits" href="https://developers.google.com/maps/documentation/directions/?hl=it#Limits" target="_blank">limite</a> di 2500 richieste giornaliere e 8 punti intermedi per richiesta. L&#8217;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.</p>
<p>Vediamo il codice javascript:</p>
<pre class="brush: jscript; title: ; notranslate">
    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 &amp;lt; directionsDisplay.length; i++){
            directionsDisplay&#x5B;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&#x5B;0]&#x5B;0], coordinates&#x5B;0]&#x5B;1]);
        var end = null;
        var waypts = new Array();
        var wCount = 0;
        var REQUEST_WAYPOINTS_LIMIT = 8;
        var i;
        for(i = 1; i &amp;lt; (coordinates.length-1); i++){
            if(wCount === REQUEST_WAYPOINTS_LIMIT){
                i++;
                end = new google.maps.LatLng(coordinates&#x5B;i]&#x5B;0], coordinates&#x5B;i]&#x5B;1]);
                drawRoute(begin, end, waypts);
                begin = end;
                wCount = 0;
                waypts = new Array();
            }
            waypts.push({
                location: new google.maps.LatLng(coordinates&#x5B;i]&#x5B;0], coordinates&#x5B;i]&#x5B;1]),
                stopover: true
            });
            wCount++;
        }
        if(waypts.length &amp;gt; 0){
            end = new google.maps.LatLng(coordinates&#x5B;coordinates.length-1]&#x5B;0], coordinates&#x5B;coordinates.length-1]&#x5B;1]);
            drawRoute(begin, end, waypts);
        }
        for(var i = 0; i &amp;lt; coordinates.length; i++){
            placeMarker(coordinates&#x5B;i]&#x5B;0], coordinates&#x5B;i]&#x5B;1]);
        }
    }
</pre>
<p>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&#8217;ultima cella dell&#8217;array, passando per tutte le altre.</p>
<p>Ho dato per scontato che la mappa sia già stata inizializzata e che la variabile <em>map</em> contenga l&#8217;oggetto <em>google.maps.Map</em>.</p>
<p>Un&#8217;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.</p><p>The post <a href="https://blog.davideferrero.com/2013/10/aggirare-le-limitazioni-delle-api-di-google-maps-per-il-calcolo-dei-percorsi/">Aggirare le limitazioni delle API di Google Maps per il calcolo dei percorsi</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://blog.davideferrero.com/2013/10/aggirare-le-limitazioni-delle-api-di-google-maps-per-il-calcolo-dei-percorsi/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Visualizzare ed eliminare foreign keys in MySQL</title>
		<link>https://blog.davideferrero.com/2013/10/visualizzare-ed-eliminare-foreign-keys-in-mysql/</link>
					<comments>https://blog.davideferrero.com/2013/10/visualizzare-ed-eliminare-foreign-keys-in-mysql/#respond</comments>
		
		<dc:creator><![CDATA[davide]]></dc:creator>
		<pubDate>Sun, 13 Oct 2013 18:05:17 +0000</pubDate>
				<category><![CDATA[HowTo]]></category>
		<category><![CDATA[Informatica]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[DB]]></category>
		<category><![CDATA[DBMS]]></category>
		<category><![CDATA[Foreign Key]]></category>
		<category><![CDATA[InnoDB]]></category>
		<guid isPermaLink="false">http://blog.davideferrero.com/?p=676</guid>

					<description><![CDATA[<p>Con l&#8217;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 [&#8230;]</p>
<p>The post <a href="https://blog.davideferrero.com/2013/10/visualizzare-ed-eliminare-foreign-keys-in-mysql/">Visualizzare ed eliminare foreign keys in MySQL</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-731" alt="MySQL" src="http://blog.davideferrero.com/wp-content/uploads/2013/10/050.jpg" width="500" height="291" srcset="https://blog.davideferrero.com/wp-content/uploads/2013/10/050.jpg 500w, https://blog.davideferrero.com/wp-content/uploads/2013/10/050-300x174.jpg 300w" sizes="auto, (max-width: 500px) 100vw, 500px" /></p>
<p>Con l&#8217;avvento di <a title="InnoDB Storage Engine" href="http://dev.mysql.com/doc/refman/5.5/en/innodb-storage-engine.html" target="_blank">InnoDB</a> su <a title="MySQL" href="http://www.mysql.it/" target="_blank">MySQL</a>ci 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:</p>
<pre class="brush: sql; title: ; notranslate">select * from KEY_COLUMN_USAGE WHERE TABLE_SCHEMA = '&lt;em&gt;database_name&lt;/em&gt;' AND TABLE_NAME = '&lt;em&gt;table_name&lt;/em&gt;'</pre>
<p>Come si può intuire, al posto di <em>database_name </em>si dovrà inserire il nome del database in cui risiede la tabella, e al posto di <em>table_name</em>si dovrà scrivere il nome della tabella dalla quale estrarre le chiavi.<br />
Una volta ottenuta la lista di foreign key, per elimare una chiave il codice sql da eseguire è:</p>
<pre class="brush: sql; title: ; notranslate">ALTER TABLE &lt;em&gt;table_name&lt;/em&gt; DROP FOREIGN KEY &lt;em&gt;foreign_key_name&lt;/em&gt;</pre>
<p><em>Table_name</em> è come sopra il nome della tabella in cui risiedono le chiavi esterne, mentre <em>foreign_key_name</em> è il nome della chiave ottenuto dalla lista estratta con la query precedente.</p><p>The post <a href="https://blog.davideferrero.com/2013/10/visualizzare-ed-eliminare-foreign-keys-in-mysql/">Visualizzare ed eliminare foreign keys in MySQL</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://blog.davideferrero.com/2013/10/visualizzare-ed-eliminare-foreign-keys-in-mysql/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Eseguire chiamate AJAX con jQuery e JSON in WordPress</title>
		<link>https://blog.davideferrero.com/2013/06/eseguire-chiamate-ajax-con-jquery-e-json-in-wordpress/</link>
					<comments>https://blog.davideferrero.com/2013/06/eseguire-chiamate-ajax-con-jquery-e-json-in-wordpress/#respond</comments>
		
		<dc:creator><![CDATA[davide]]></dc:creator>
		<pubDate>Wed, 05 Jun 2013 21:16:04 +0000</pubDate>
				<category><![CDATA[HowTo]]></category>
		<category><![CDATA[Informatica]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Wordpress]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[PHP]]></category>
		<guid isPermaLink="false">http://blog.davideferrero.com/?p=665</guid>

					<description><![CDATA[<p>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&#8217;interfaccia del wp-admin. Nell&#8217;esempio in questione, la chiamata AJAX restituirà un file JSON formato davvero utile per rappresentare i dati restituiti da una [&#8230;]</p>
<p>The post <a href="https://blog.davideferrero.com/2013/06/eseguire-chiamate-ajax-con-jquery-e-json-in-wordpress/">Eseguire chiamate AJAX con jQuery e JSON in WordPress</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-733" alt="Ajax and WordPress" src="http://blog.davideferrero.com/wp-content/uploads/2013/06/049.jpg" width="200" height="200" srcset="https://blog.davideferrero.com/wp-content/uploads/2013/06/049.jpg 200w, https://blog.davideferrero.com/wp-content/uploads/2013/06/049-150x150.jpg 150w" sizes="auto, (max-width: 200px) 100vw, 200px" /></p>
<p>Succede sempre più di frequente di dover effettuare delle chiamate <a title="Ajax" href="http://it.wikipedia.org/wiki/AJAX" target="_blank">ajax</a> in <a title="Wordpress" href="http://wordpress.org/" target="_blank">WordPress</a>. In questo articolo vedremo come effettuare delle chiamate asincrone senza dover creare nuove pagine WordPress ma sfruttando lo script utilizzato dall&#8217;interfaccia del wp-admin.<br />
Nell&#8217;esempio in questione, la chiamata AJAX restituirà un file <a title="JSON" href="http://www.json.org/" target="_blank">JSON</a> formato davvero utile per rappresentare i dati restituiti da una query. Lato javascript useremo la funzione $.getJSON(&#8230;) di <a title="jQuery" href="http://jquery.com/" target="_blank">jQuery</a> mentre lato server scriveremo il nostro script all&#8217;interno del file functions.php presente in qualsiasi tema WordPress.</p>
<p>Per prima cosa dobbiamo creare la corrispondenza tra una nuova <em>action </em>e la nostra funzione <a title="PHP" href="http://php.net/" target="_blank">php</a>:</p>
<pre class="brush: php; title: ; notranslate">add_action('wp_ajax_myaction', 'my_function');</pre>
<p>Fatto ciò possiamo scrivere la nostra funzione <em>my_function</em> la quale corrisponderà all&#8217;azione <em>myaction</em> (il nome è puramente indicativo, potete chiamare l&#8217;azione e la funzione come preferite):</p>
<pre class="brush: php; title: ; notranslate">function my_function() {
  global $wpdb;
  $id = $_GET&#x5B;'id'];
  $rows = array();
  $q = &quot;SELECT * FROM my_table WHERE id = &quot;.$id;
  $rows&#x5B;'results'] = $wpdb-&gt;get_results($q, ARRAY_A);
  if(count($rows) &lt;= 0){
    return false;
  }
  echo json_encode($rows);
  exit();
}</pre>
<p>In questo script trovate tutto l&#8217;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 <em>wpdb</em> effettueremo la query sul database. La <em>json_encode</em> trasformerà l&#8217;array associativo con i record letti tramite la SELECT in una stringa JSON e la stamperemo a video tramite l&#8217;<em>echo</em>. Non dimenticate la <em>exit()</em> finale perchè altrimenti verrà stampato uno &#8220;0&#8221; che vi metterà in difficoltà nel parsificare il JSON.</p>
<p>Un ultimo particolare di cui tenere conto è che la <em>add_action</em> crea un&#8217;azione per l&#8217;admin-ajax.php che è un file accessibile solo da utenti loggati, quindi per consentire l&#8217;esecuzione dell&#8217;azione sia da utenti registrati sia da ospiti sarà necessario aggiungere un&#8217;ulteriore linea di codice come questa:</p>
<pre class="brush: php; title: ; notranslate">add_action('wp_ajax_nopriv_myaction', 'my_function');</pre>
<p>Dopo aver completato lo script PHP possiamo passare al lato client, con il codice javascript per la chiamata della funzione:</p>
<pre class="brush: jscript; title: ; notranslate">$jQ.getJSON('&lt;?php echo get_bloginfo('url'); ?&gt;/wp-admin/admin-ajax.php',{action: 'myaction',id: 'tuo_id'}, function(json){...Codice javascript per parsificare il json...}</pre>
<p>Ho omesso l&#8217;inclusione di jquery in WordPress, ma potete trovare come fare in <a title="Includere jQuery nel proprio tema wordpress" href="http://blog.davideferrero.com/2010/04/includere-jquery-nel-tema-wordpress/">un mio precedente articolo</a> che trattava l&#8217;argomento nello specifico.</p>
<p>A questo punto non vi resta che sbizzarrirvi con le chiamate ajax nel vostro template oppure dai vostri plugin (in quest&#8217;ultimo caso basta spostare il codice PHP in un file del vostro plugin).</p><p>The post <a href="https://blog.davideferrero.com/2013/06/eseguire-chiamate-ajax-con-jquery-e-json-in-wordpress/">Eseguire chiamate AJAX con jQuery e JSON in WordPress</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://blog.davideferrero.com/2013/06/eseguire-chiamate-ajax-con-jquery-e-json-in-wordpress/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Piccoli traguardi&#8230; piccole soddisfazioni, 2000 visite mensili!</title>
		<link>https://blog.davideferrero.com/2012/09/piccoli-traguardi-piccole-soddisfazioni-2000-visite-mensili/</link>
					<comments>https://blog.davideferrero.com/2012/09/piccoli-traguardi-piccole-soddisfazioni-2000-visite-mensili/#respond</comments>
		
		<dc:creator><![CDATA[davide]]></dc:creator>
		<pubDate>Thu, 27 Sep 2012 19:01:26 +0000</pubDate>
				<category><![CDATA[Curiosità]]></category>
		<category><![CDATA[Informatica]]></category>
		<category><![CDATA[Notizie]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Statistiche]]></category>
		<category><![CDATA[Traguardi]]></category>
		<category><![CDATA[Visite]]></category>
		<category><![CDATA[Visite mensili]]></category>
		<guid isPermaLink="false">http://blog.davideferrero.com/?p=630</guid>

					<description><![CDATA[<p>Cari lettori del blog, oggi ho raggiunto un piccolo ma importante traguardo&#8230; 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 [&#8230;]</p>
<p>The post <a href="https://blog.davideferrero.com/2012/09/piccoli-traguardi-piccole-soddisfazioni-2000-visite-mensili/">Piccoli traguardi… piccole soddisfazioni, 2000 visite mensili!</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-735" alt="Report Google Analytics" src="http://blog.davideferrero.com/wp-content/uploads/2012/09/048.jpg" width="650" height="240" srcset="https://blog.davideferrero.com/wp-content/uploads/2012/09/048.jpg 650w, https://blog.davideferrero.com/wp-content/uploads/2012/09/048-300x110.jpg 300w" sizes="auto, (max-width: 650px) 100vw, 650px" /></p>
<p>Cari lettori del blog, oggi ho raggiunto un piccolo ma importante traguardo&#8230; I dati di <a title="Google Analytics" href="http://www.google.com/analytics/" target="_blank">google analytics</a> parlano chiaro, sono state sorpassate le 2000 visite mensili e per questo voglio condividere con voi alcune statistiche di cui vado fiero.</p>
<p>Dal 27 agosto al 26 settembre <a title="Blog di Davide Ferrero, web developer" href="http://blog.davideferrero.com">questo blog</a> ha ricevuto 2004 visite, con 1672 visitatori unici e 2369 visualizzazioni di pagina di cui 2175 uniche. L&#8217;80,84% delle visite sono nuove e ovviamente il paese predominante è l&#8217;italia con 1910 visite  delle quali 1853 in lingua italiana.</p>
<p>I tre articoli più popolari per il momento sono nell&#8217;ordine &#8220;<a title="Creare un web service con soap e php" href="http://blog.davideferrero.com/2010/10/creare-un-web-service-con-soap-e-php/">Creare un web service con soap e php</a>&#8221; con 401 visualizzazioni, &#8220;<a title="Sincronizzare Google Calendar con iCal su Mac e iPhone" href="http://blog.davideferrero.com/2010/08/sincronizzare-google-calendar-con-ical-su-mac-e-iphone/">Sincronizzare Google Calendar con iCal su Mac e iPhone</a>&#8221; con 395 visualizzazioni e &#8220;<a title="Calibrare la batteria di un Macbook Pro e non solo…" href="http://blog.davideferrero.com/2011/02/calibrare-la-batteria-di-macbook-pro-e-pc-portatili/">Calibrare la batteria di un Macbook Pro e non solo…</a>&#8221; con 323 visualizzazioni.</p>
<p>Grazie a tutti voi che mi leggete, continuate a farlo! Mi auguro di poter continuare a scrivere articoli (spero) interessanti per accrescere questi numeri!</p>
<p>A presto, Davide.</p><p>The post <a href="https://blog.davideferrero.com/2012/09/piccoli-traguardi-piccole-soddisfazioni-2000-visite-mensili/">Piccoli traguardi… piccole soddisfazioni, 2000 visite mensili!</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://blog.davideferrero.com/2012/09/piccoli-traguardi-piccole-soddisfazioni-2000-visite-mensili/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Eseguire un&#8217;applicazione Django su ubuntu server con nginx, gunicorn, upstart e mysql (DUNG stack)</title>
		<link>https://blog.davideferrero.com/2012/09/eseguire-unapplicazione-django-su-ubuntu-server-con-nginx-gunicorn-mysql-dung-stack/</link>
					<comments>https://blog.davideferrero.com/2012/09/eseguire-unapplicazione-django-su-ubuntu-server-con-nginx-gunicorn-mysql-dung-stack/#comments</comments>
		
		<dc:creator><![CDATA[davide]]></dc:creator>
		<pubDate>Wed, 26 Sep 2012 22:23:28 +0000</pubDate>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[HowTo]]></category>
		<category><![CDATA[Informatica]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Gunicorn]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Nginx]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[Upstart]]></category>
		<guid isPermaLink="false">http://blog.davideferrero.com/?p=604</guid>

					<description><![CDATA[<p>Oggi torno a scrivere sul blog per raccontare come eseguire il deploy di un&#8217;applicazione Django su ubuntu server con Nginx come web server, Gunicorn come application server WSGI e MySQL come DBMS. Inizialmente per ospitare un&#8217;applicazione scritta con il framework Django utilizzavo un classico stack in stile LAMPP (Linux + Apache + mod_wsgi). Successivamente per cercare di limitare l&#8217;utilizzo di [&#8230;]</p>
<p>The post <a href="https://blog.davideferrero.com/2012/09/eseguire-unapplicazione-django-su-ubuntu-server-con-nginx-gunicorn-mysql-dung-stack/">Eseguire un’applicazione Django su ubuntu server con nginx, gunicorn, upstart e mysql (DUNG stack)</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-740" alt="Gunicorn" src="http://blog.davideferrero.com/wp-content/uploads/2012/09/047-600x130.jpg" width="600" height="130" srcset="https://blog.davideferrero.com/wp-content/uploads/2012/09/047-600x130.jpg 600w, https://blog.davideferrero.com/wp-content/uploads/2012/09/047-300x65.jpg 300w, https://blog.davideferrero.com/wp-content/uploads/2012/09/047.jpg 939w" sizes="auto, (max-width: 600px) 100vw, 600px" /></p>
<p>Oggi torno a scrivere sul blog per raccontare come eseguire il deploy di un&#8217;applicazione <a title="Django framework" href="https://www.djangoproject.com/" target="_blank">Django</a> su ubuntu server con <a title="Nginx" href="http://nginx.org/" target="_blank">Nginx</a> come web server, <a title="Gunicorn, green unicorn" href="http://gunicorn.org/" target="_blank">Gunicorn</a> come application server WSGI e <a title="MySQL" href="http://www.mysql.it/" target="_blank">MySQL</a> come DBMS.</p>
<p>Inizialmente per ospitare un&#8217;applicazione scritta con il framework Django utilizzavo un classico stack in stile LAMPP (Linux + <a title="Apache" href="http://www.apache.org/" target="_blank">Apache</a> + <a title="mod_wsgi" href="http://code.google.com/p/modwsgi/" target="_blank">mod_wsgi</a>). Successivamente per cercare di limitare l&#8217;utilizzo di ram ho scoperto (grazie al <a title="Instagram Engineering blog" href="http://instagram-engineering.tumblr.com/" target="_blank">blog degli ingegneri di instagram</a>) lo stack DUNG che rappresenta la configurazione con nginx + gunicorn + ubuntu.</p>
<p>Non appena si iniziano le configurazioni si comprendono la semplicità e la velocità di messa a punto del nuovo stack. Nginx usa file di configurazione scritti con una sintassi simile ad un linguaggio di programmazione, molto più semplici da comprendere e da scrivere per chi ha poca dimestichezza con queste cose.</p>
<p>Per prima cosa installiamo nell&#8217;ordine <a title="Installare MySQL su ubuntu server" href="http://help.ubuntu-it.org/10.04/ubuntu/serverguide/it/mysql.html" target="_blank">mysql</a> e <a title="Installare nginx su ubuntu" href="http://wiki.nginx.org/Install#Official_Debian.2FUbuntu_packages" target="_blank">nginx</a>, successivamente <a title="Installazione di django" href="https://docs.djangoproject.com/en/1.4/intro/install/" target="_blank">installiamo django</a>.</p>
<p>Fatto ciò, tramite easy_install possiamo installare Gunicorn:</p>
<pre class="brush: bash; title: ; notranslate">sudo easy_install gunicorn</pre>
<p>A questo punto dobbiamo configurare nginx come proxy server per le richieste: tutto ciò che riguarda i file statici (immagini, css, js, ecc&#8230;) verrà servito direttamente da nginx mentre le richieste inerenti il codice python dovranno essere girate al server WSGI (gunicorn nel nostro caso) che le eseguirà e restituirà la pagina risultante.</p>
<p>Come per apache i file di configurazione dei vari siti sono in <em>/etc/nginx/sites-available </em>(invece di <em>/etc/apache/sites-available</em>), per cui creiamo il file di configurazione per la nostra applicazione django in questo modo:</p>
<pre class="brush: bash; title: ; notranslate">upstream project {
        server 127.0.0.1:8200 fail_timeout=0;
        server 127.0.0.1:8201 fail_timeout=0;
}

server {
        listen 80;
        server_name mydomain.com www.mydomain.com;
        access_log /var/log/nginx/mydomain_access.log;
        error_log /var/log/nginx/mydomain_error.log;

        root /srv/django_srv/mydomain/app;

        location / {
                proxy_set_header Host $host;
                if (!-f $request_filename){
                        proxy_pass http://project;
                        break;
                }

        }
        location /upload  {
                alias /srv/django_srv/mydomain/uploads;
                }
        location /static  {
                alias /srv/django_srv/mydomain/app/_statics;
        }
        location /admin/media {
                alias /opt/Django-1.3.1/django/contrib/admin/media;
        }
}</pre>
<p>Come potete vedere nel blocco di configurazione <em>upstream project</em> a questo punto dobbiamo configurare gunicorn in modo da farlo rispondere sulla porta 8200 e 8201. In questo modo quando caricheremo aggiornamenti del nostro progetto e dovremmo riavviare gunicorn, il sito non sarà mai irraggiungibile, inoltre se il processo gunicorn dovesse crollare per qualche motivo ce ne sarà sempre un altro disponibile. Gli alias che vedete sono per i file uploadati dagli utenti tramite l&#8217;applicazione, i file statici del sito e i file statici per il backend amministrativo (per questi ultimi dovete dare il path alla cartella di installazione di Django). Dopo aver salvato questo file create un link simbolico nella cartella effettiva dei siti di nginx:</p>
<pre class="brush: bash; title: ; notranslate">ln -s /etc/nginx/sites-available/mydomain.com /etc/nginx/sites-enabled/mydomain.com</pre>
<p>Per avviare gunicorn, essendo su ubuntu, utilizziamo <a title="Upstart" href="http://upstart.ubuntu.com/" target="_blank">upstart</a> il nuovo sistema per avviare tasks e servizi all&#8217;avvio del sistema. Creiamo il file /etc/init/gunicorn_8200.conf e copiamo le seguenti istruzioni:</p>
<pre class="brush: bash; title: ; notranslate">description &quot;Gunicorn Django on 127.0.0.1:8200&quot;
start on runlevel &#x5B;2345]
stop on runlevel &#x5B;06]
respawn
respawn limit 10 5
exec /usr/local/bin/gunicorn_django --bind=127.0.0.1:8200 --workers=2 --access-logfile=/var/log/gunicorn/8200_access.log --error-logfile=/var/log/gunicorn/8200_error.log --daemon /srv/django_srv/mydomain/app/settings.py</pre>
<p>Con queste istruzioni diciamo al processo gunicorn di ripartire in caso di crash (<em>respawn</em>) di rispondere all&#8217;indirizzo 127.0.0.1 sulla porta 8200 (<em>&#8211;bind</em>) di partire come demone (<em>&#8211;daemon</em>) e gli diamo i percorsi dei file di log e del file di settings della nostra applicazione.</p>
<p>A questo punto riavviamo il server per verificare che anche upstart funzioni:</p>
<pre class="brush: bash; title: ; notranslate">shutdown -r now</pre>
<p>Il gioco è fatto e la nostra applicazione è pronta per essere utilizzata. I file del progetto django (in base a questa configurazione) devono risiedere in <em>/srv/django_srv/mydomain/app</em>, mentre i file di upload sono in <em>/srv/django_srv/mydomain/uploads</em> per fare in modo che non siano all&#8217;interno dell&#8217;applicazione e che siano facilmente backuppabili ;)</p>
<p>Spero di essere stato esaustivo, di sicuro con questa configurazione vi potrete accorgere del notevole risparmio di ram rispetto ad un classico stack che utilizza apache come webserver.</p><p>The post <a href="https://blog.davideferrero.com/2012/09/eseguire-unapplicazione-django-su-ubuntu-server-con-nginx-gunicorn-mysql-dung-stack/">Eseguire un’applicazione Django su ubuntu server con nginx, gunicorn, upstart e mysql (DUNG stack)</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://blog.davideferrero.com/2012/09/eseguire-unapplicazione-django-su-ubuntu-server-con-nginx-gunicorn-mysql-dung-stack/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Server virtualizzato con VirtualBox 4.0 su Ubuntu Server 10.04 LTS</title>
		<link>https://blog.davideferrero.com/2012/04/server-virtualizzati-con-virtualbox-4-su-ubuntu-server-10-04/</link>
					<comments>https://blog.davideferrero.com/2012/04/server-virtualizzati-con-virtualbox-4-su-ubuntu-server-10-04/#comments</comments>
		
		<dc:creator><![CDATA[davide]]></dc:creator>
		<pubDate>Wed, 25 Apr 2012 14:04:45 +0000</pubDate>
				<category><![CDATA[HowTo]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[macchina virtuale]]></category>
		<category><![CDATA[Server]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[Ubuntu Server 10.04 LTS]]></category>
		<category><![CDATA[virtual machine]]></category>
		<category><![CDATA[virtualbox]]></category>
		<guid isPermaLink="false">http://blog.davideferrero.com/?p=591</guid>

					<description><![CDATA[<p>Oggi inauguro la nuova grafica del blog con un articolo molto interessante. Questo tutorial vi aiuterà a virtualizzare dei server con VirtualBox da linea di comando. Ho installato virtualbox 4.0 su una macchina ubuntu server 10.04, ma repository a parte penso che vada bene su qualsiasi versione di ubuntu e più in generale su qualsiasi [&#8230;]</p>
<p>The post <a href="https://blog.davideferrero.com/2012/04/server-virtualizzati-con-virtualbox-4-su-ubuntu-server-10-04/">Server virtualizzato con VirtualBox 4.0 su Ubuntu Server 10.04 LTS</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-742" alt="Oracle Virtualbox" src="http://blog.davideferrero.com/wp-content/uploads/2012/04/046.jpg" width="140" height="180" /></p>
<p>Oggi inauguro la nuova grafica del blog con un articolo molto interessante. Questo tutorial vi aiuterà a virtualizzare dei server con <a title="VirtualBox" href="https://www.virtualbox.org/" target="_blank">VirtualBox</a> da linea di comando.<br />
Ho installato virtualbox 4.0 su una macchina ubuntu server 10.04, ma repository a parte penso che vada bene su qualsiasi versione di ubuntu e più in generale su qualsiasi debian.</p>
<p>Per chi lavora come me su ubuntu server 10.04 per prima cosa bisogna aggiungere il repository di virtualbox nei sorgenti apt. Aprite il file source.list:</p>
<pre class="brush: bash; title: ; notranslate">sudo vim /etc/apt/sources.list</pre>
<p>E aggiungete in fondo la linea:</p>
<pre class="brush: bash; title: ; notranslate">deb http://download.virtualbox.org/virtualbox/debian lucid contrib</pre>
<p>Salvate e chiudete e scaricate la chiave pubblica:</p>
<pre class="brush: bash; title: ; notranslate">wget -q http://download.virtualbox.org/virtualbox/debian/oracle_vbox.asc -O- | sudo apt-key add -</pre>
<p>A questo punto aggiornate:</p>
<pre class="brush: bash; title: ; notranslate">sudo apt-get update</pre>
<p>..e installate il software necessario:</p>
<pre class="brush: bash; title: ; notranslate">sudo apt-get install linux-headers-$(uname -r) build-essential virtualbox-4.0 dkms</pre>
<p>Il pacchetto dkms serve per far sì che ogni volta che il kernel verrà aggiornato verrà aggiornato automaticamente anche virtualbox.</p>
<p>A questo punto scaricate l&#8217;extension pack di virtualbox</p>
<pre class="brush: bash; title: ; notranslate">cd /tmp
wget http://download.virtualbox.org/virtualbox/4.0.16/Oracle_VM_VirtualBox_Extension_Pack-4.0.16-75491.vbox-extpack
sudo VBoxManage extpack install Oracle_VM_VirtualBox_Extension_Pack-4.0.16-75491.vbox-extpack</pre>
<p>Ora dovrete aggiungere il vostro utente al gruppo utenti di virtualbox:</p>
<pre class="brush: bash; title: ; notranslate">sudo adduser your_user vboxusers</pre>
<p>Ora la configurazione di virtualbox è terminata, possiamo procedere con la creazione di una nuova virtual machine.</p>
<pre class="brush: bash; title: ; notranslate">VBoxManage createvm --name "ubu_srv_1" --register
VBoxManage modifyvm "ubu_srv_1" --memory 512 --acpi on --boot1 dvd --nic1 bridged --bridgeadapter1 eth0
VBoxManage createhd --filename /home/your_user/vbox/ubu_srv_1/ubu_srv_1.vdi --size 10000
VBoxManage storagectl "ubu_srv_1" --name "IDE Controller" --add ide
VBoxManage storageattach "ubu_srv_1" --storagectl "IDE Controller" --port 0 --device 0 --type hdd --medium /home/your_user/vbox/ubu_srv_1/ubu_srv_1.vdi
VBoxManage storageattach "ubu_srv_1" --storagectl "IDE Controller" --port 1 --device 0 --type dvddrive --medium /home/your_user/downloads/ubuntu-10.04.4-server-amd64.iso</pre>
<p>Con queste istruzioni la nuova macchina virtuale è pronta.</p>
<p>Ora per il primo lancio vi consiglio di usare VBoxHeadless che oltre a lanciare la vm appena creata metterà in piedi un server VRDP, in modo che possiate accedere alla macchina con un client di desktop remoto. Per cui, settiamo la porta del vrdp:</p>
<pre class="brush: bash; title: ; notranslate">VBoxManage modifyvm "ubu_srv_1" --vrde-port 9800</pre>
<p>..e lanciamo la macchina virtuale (abbiate cura di mettere la &#8220;&amp;&#8221; al fondo del comando in modo da poter continuare sulla stessa shell senza chiudere bruscamente il processo della virtual machine):</p>
<pre class="brush: bash; title: ; notranslate">VBoxHeadless --startvm "ubu_srv_1" &</pre>
<p>Quindi aprite il vostro client di desktop remoto preferito e collegatevi all&#8217;ip della vostra macchina su cui avete installato virtualbox aggiungendo &#8220;:9800&#8221;. Il mio indirizzo a cui rispondeva il server rdp era ad esempio 192.168.0.200:9800.<br />
Potete quindi installare normalmente ubuntu server come se foste su una macchina fisica. Finita l&#8217;installazione riavviando la macchina partirà il sistema in automatico. Collegatevi e come prima cosa controllate l&#8217;ip (meglio assegnarne uno fisso). Prima di poter dire di avere la vm pronta dobbiamo fare in modo che al prossimo lancio non parta più l&#8217;immagine di installazione, per cui spegnete la macchina e ritornate sulla shell del server virtualbox:</p>
<pre class="brush: bash; title: ; notranslate">VBoxManage modifyvm "ubu_srv_1" --boot1 disk</pre>
<p>Adesso siete davvero pronti per lanciare la vostra nuova virtual machine. I passi successivi servono per ottimizzare l&#8217;utilizzo di ram del vostro server.</p>
<p>Riavviate la macchina fisica che ospita la/le macchina/e virtuale/i e ricollegatevi. Da shell modificate ancora la vm con il seguente comando per non lanciare il server vrdp quando avviate la vm, così da occupare la sola ram indicata per la vostra vm:</p>
<pre class="brush: bash; title: ; notranslate">VBoxManage modifyvm "ubu_srv_1" --vrde off</pre>
<p>Ora potete nuovamente lanciare la vostra macchina virtuale con il comando:</p>
<pre class="brush: bash; title: ; notranslate">VBoxManage startvm "ubu_srv_1" --type headless &</pre>
<p>Per tutti i comandi di VBoxManage fate riferimento all&#8217;help:</p>
<pre class="brush: bash; title: ; notranslate">VBoxManage --help</pre>
<p>Per spegnere o mettere in pausa la macchina i comandi sono:</p>
<pre class="brush: bash; title: ; notranslate">VBoxManage controlvm "ubu_srv_1" poweroff
VBoxManage controlvm "ubu_srv_1" pause</pre>
<p>Buon divertimento!</p><p>The post <a href="https://blog.davideferrero.com/2012/04/server-virtualizzati-con-virtualbox-4-su-ubuntu-server-10-04/">Server virtualizzato con VirtualBox 4.0 su Ubuntu Server 10.04 LTS</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://blog.davideferrero.com/2012/04/server-virtualizzati-con-virtualbox-4-su-ubuntu-server-10-04/feed/</wfw:commentRss>
			<slash:comments>7</slash:comments>
		
		
			</item>
		<item>
		<title>iPad 3 o iPad HD ?</title>
		<link>https://blog.davideferrero.com/2012/03/ipad-3-o-ipad-hd/</link>
					<comments>https://blog.davideferrero.com/2012/03/ipad-3-o-ipad-hd/#respond</comments>
		
		<dc:creator><![CDATA[davide]]></dc:creator>
		<pubDate>Tue, 06 Mar 2012 21:44:51 +0000</pubDate>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[Informatica]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPad 3]]></category>
		<category><![CDATA[Tim Cook]]></category>
		<guid isPermaLink="false">http://blog.davideferrero.com/?p=572</guid>

					<description><![CDATA[<p>I dubbi sono tanti.. Ad iniziare dal nome (o i nomi), le indiscrezione parlano di un iPad HD, ma siamo sicuri che si tratti davvero della nuova versione del gioiello di casa Apple e non di un? Le indiscrezioni riguardano: Retina display: stessa dimensione dello schermo ma doppia densità di pixel così da permettere una risoluzione [&#8230;]</p>
<p>The post <a href="https://blog.davideferrero.com/2012/03/ipad-3-o-ipad-hd/">iPad 3 o iPad HD ?</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>I dubbi sono tanti.. Ad iniziare dal nome (o i nomi), le indiscrezione parlano di un iPad HD, ma siamo sicuri che si tratti davvero della nuova versione del gioiello di casa Apple e non di un?</p>
<p>Le indiscrezioni riguardano:</p>
<ul>
<li>Retina display: stessa dimensione dello schermo ma doppia densità di pixel così da permettere una risoluzione dello schermo raddoppiata rispetto alle vecchie versioni.</li>
<li>Batteria con autonomia maggiore: probabilmente questo porterà un leggero incremento di spessore</li>
<li>Processore quad core: anche per questo serve una batteria più performante, ma sicuramente incrementerà le prestazioni</li>
<li>Assenza del pulsante home: un recente brevetto Apple parla di una nuova tecnologia per utilizzare nuove gestures che sarebbero in grado di sostituire le funzioni dell&#8217;ormai immancabile pulsante rotondo presente su tutti i device mobili di Apple</li>
<li>Fotocamera migliorata: l&#8217;attuale fotocamera non consente di scattare foto di buona qualità, probabilmente verrà inserita una fotocamera molto simile a quella di iPhone 4S</li>
</ul>
<p>Per sapere quali di questi punti sono azzeccati, bisognerà aspettare le 19 di domani, quando Tim Cook salirà sul palco dello Yerba Buena Center di San Francisco.</p>
<p>Ci sarà anche il One More Thing?</p>
<p>Voi cosa ne pensate?</p>
<p>&nbsp;</p>
<p>Se domani sera volete seguire tutte le novità in diretta, potrete farlo <a title="iPad 3 Liveblog di Matteo Bovetti" href="http://www.matteobovetti.com/blog/ipad-3-apple-event-liveblog/" target="_blank">a questo indirizzo</a> sul blog del mio amico <a title="Matteo Bovetti's blog" href="http://www.matteobovetti.com" target="_blank">Matteo Bovetti</a>!</p><p>The post <a href="https://blog.davideferrero.com/2012/03/ipad-3-o-ipad-hd/">iPad 3 o iPad HD ?</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://blog.davideferrero.com/2012/03/ipad-3-o-ipad-hd/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Siri incontra Siri</title>
		<link>https://blog.davideferrero.com/2011/11/siri-incontra-siri-apple-iphone-4s/</link>
					<comments>https://blog.davideferrero.com/2011/11/siri-incontra-siri-apple-iphone-4s/#respond</comments>
		
		<dc:creator><![CDATA[davide]]></dc:creator>
		<pubDate>Sun, 13 Nov 2011 15:55:11 +0000</pubDate>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[Divertimento]]></category>
		<category><![CDATA[Informatica]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[iPhone 4S]]></category>
		<category><![CDATA[SIRI]]></category>
		<guid isPermaLink="false">http://blog.davideferrero.com/?p=569</guid>

					<description><![CDATA[<p>Ecco cosa succede quando due iPhone 4S con Siri si incontrano:</p>
<p>The post <a href="https://blog.davideferrero.com/2011/11/siri-incontra-siri-apple-iphone-4s/">Siri incontra Siri</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>Ecco cosa succede quando due iPhone 4S con Siri si incontrano:</p>
<p><iframe loading="lazy" src="http://www.youtube.com/embed/XBRXA8zmJr8?wmode=opaque" frameborder="0" width="560" height="315"></iframe></p><p>The post <a href="https://blog.davideferrero.com/2011/11/siri-incontra-siri-apple-iphone-4s/">Siri incontra Siri</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://blog.davideferrero.com/2011/11/siri-incontra-siri-apple-iphone-4s/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Commenti annidati in wordpress</title>
		<link>https://blog.davideferrero.com/2011/10/commenti-annidati-in-wordpress/</link>
					<comments>https://blog.davideferrero.com/2011/10/commenti-annidati-in-wordpress/#respond</comments>
		
		<dc:creator><![CDATA[davide]]></dc:creator>
		<pubDate>Sun, 23 Oct 2011 13:16:48 +0000</pubDate>
				<category><![CDATA[HowTo]]></category>
		<category><![CDATA[Informatica]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Wordpress]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[html]]></category>
		<guid isPermaLink="false">http://blog.davideferrero.com/?p=562</guid>

					<description><![CDATA[<p>In questi giorni sono ritornato a lavorare un po&#8217; sul mio amato wordpress. Oltre a segnalarvi un fantastico restyle grafico del tema di backend per l&#8217;amministrazione del blog che potete trovare aggiornando wordpress alla versione 3 oggi voglio parlarvi di come modificare il tema dei commenti. Questa piccola modifica servirà per visualizzare i commenti annidati, [&#8230;]</p>
<p>The post <a href="https://blog.davideferrero.com/2011/10/commenti-annidati-in-wordpress/">Commenti annidati in wordpress</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>In questi giorni sono ritornato a lavorare un po&#8217; sul mio amato <a title="Wordpress" href="http://wordpress.org/" target="_blank">wordpress</a>.</p>
<p>Oltre a segnalarvi un fantastico restyle grafico del tema di backend per l&#8217;amministrazione del blog che potete trovare aggiornando wordpress alla versione 3 oggi voglio parlarvi di come modificare il tema dei commenti.</p>
<p>Questa piccola modifica servirà per visualizzare i commenti annidati, ossia far comparire le risposte ad un commento all&#8217;interno del commento stesso, per migliorare la discussione e permettere a chi legge per la prima volta tutti i commenti, chi ha risposto a chi e così via.</p>
<p>WordPress ammette di default una profondità di 5 commenti annidati, ma potete impostarla a piacere tramite il menu &#8220;Impostazioni&#8221;-&gt;&#8221;Discussione&#8221;.</p>
<p>Se utilizzate uno dei tanti temi scaricati dall&#8217;archivio di wordpress verificate solamente che il tema sia aggiornato e di norma dovrebbe già includere questa funzione.</p>
<p>Se invece come me sviluppate spesso temi partendo da zero e partite da un tema semplice e magari non aggiornato alle ultime versioni, dovrete compiere alcuni semplici passi:</p>
<ol>
<li>Nell&#8217;header.php (il file della testata), aggiungete una riga sopra al &#8220;wp_head()&#8221; con questo codice:
<pre class="brush: php; title: ; notranslate">&lt;?php if( is_singular() ) wp_enqueue_script( ‘comment-reply’ ); ?&gt;</pre>
</li>
<li>Nel file comments.php dove troverete il tag &#8220;ol&#8221; con all&#8217;interno il tag &#8220;li&#8221; che ha come classe css &#8220;comment&#8221; sostituite tutto il blocco con la semplice riga
<pre class="brush: xml; title: ; notranslate">&lt;ol class=&quot;commentlist&quot;&gt;
&lt;?php wp_list_comments(); ?&gt;
&lt;/ol&gt;</pre>
</li>
<li>A questo punto non vi resta che editare il vostro css e inserire uno stile personalizzato per i vari livelli di profondità dei commenti, per selezionare il tag &#8220;li&#8221; relativo al tag &#8220;ul&#8221; dei commenti inserite in testa al selettore css la classe &#8220;.commentlist&#8221; e il gioco è fatto!</li>
</ol>
<p>In pochi e semplici passi avrete così una più chiara visione dei commenti e soprattutto della discussione.</p>
<p>Da notare è che il requisito minimo per poter sfruttare questa funzionalità è quello di avere wordpress 2.7 o versione superiore.</p><p>The post <a href="https://blog.davideferrero.com/2011/10/commenti-annidati-in-wordpress/">Commenti annidati in wordpress</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://blog.davideferrero.com/2011/10/commenti-annidati-in-wordpress/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Installare Django 1.3 su Mac OS X 10.7 Lion e XAMPP 1.7.3</title>
		<link>https://blog.davideferrero.com/2011/07/installare-django-1-3-mac-os-x-10-7-lion-xampp-1-7-3/</link>
					<comments>https://blog.davideferrero.com/2011/07/installare-django-1-3-mac-os-x-10-7-lion-xampp-1-7-3/#respond</comments>
		
		<dc:creator><![CDATA[davide]]></dc:creator>
		<pubDate>Sat, 30 Jul 2011 18:46:35 +0000</pubDate>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[HowTo]]></category>
		<category><![CDATA[Informatica]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Lion]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Web development]]></category>
		<category><![CDATA[XAMPP]]></category>
		<guid isPermaLink="false">http://blog.davideferrero.com/?p=558</guid>

					<description><![CDATA[<p>Se anche voi come me siete curiosi utilizzatori di mac, in questi giorni sarete sicuramente stati tentati di installare l&#8217;ultima versione di OS X, ovvero la major release 10.7 denominata &#8220;Lion&#8221;. Se non avete ancora provveduto all&#8217;aggiornamento, ma siete in procinto di farlo, vi consiglio quest&#8217;ottima guida di macitynet (onde evitare problemi al primo avvio di [&#8230;]</p>
<p>The post <a href="https://blog.davideferrero.com/2011/07/installare-django-1-3-mac-os-x-10-7-lion-xampp-1-7-3/">Installare Django 1.3 su Mac OS X 10.7 Lion e XAMPP 1.7.3</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>Se anche voi come me siete curiosi utilizzatori di mac, in questi giorni sarete sicuramente stati tentati di installare l&#8217;ultima versione di OS X, ovvero la major release 10.7 denominata &#8220;Lion&#8221;.</p>
<p>Se non avete ancora provveduto all&#8217;aggiornamento, ma siete in procinto di farlo, vi consiglio <a title="Guida passo passo all'installazione di Lion" href="http://www.macitynet.it/macity/articolo/OS-X-10.7-Lion-guida-allinstallazione-passo-dopo-passo/aA52834" target="_blank">quest&#8217;ottima guida di macitynet</a> (onde evitare problemi al primo avvio di Lion).</p>
<p>Terminato l&#8217;aggiornamento sembrava tutto apparentemente funzionante, fino a quando non ho tentato di avviare il server di sviluppo di <a title="Django web framework" href="https://www.djangoproject.com/" target="_blank">django</a>. Non ricordo con precisione l&#8217;errore ma il succo era che il driver per la connessione al db non era più funzionante. Ingenuamente ho disinstallato <a title="Mysql-Python" href="http://sourceforge.net/projects/mysql-python/" target="_blank">mysql-python</a>(conosciuto anche come mysqldb) credendo fosse sufficiente una reinstallazione&#8230;. ripeto: ingenuo. ;-)</p>
<p>Lanciando il comando:</p>
<pre class="brush: python; title: ; notranslate">sudo python setup.py build</pre>
<p>ottenevo una <em>sbrodolata</em> di errori relativi a librerie gcc. A fiuto ho quindi reinstallato xcode (scaricabile gratuitamente dall&#8217;app store) e rilanciato la build di mysql-python&#8230; ancora errori, ma quelli precedenti sembravano risolti. Ora le rogne venivano dal mysql_config mancante&#8230; Ho scoperto che nella cartella di installazione di mysql-python c&#8217;è un file site.cfg che contiene questa famosa variabile mysql_config, la quale deve contenere il path al file mysql_config (file di configurazione di mysql). Per me che uso <a title="XAMPP 1.7.3 per Mac" href="http://www.apachefriends.org/it/xampp-macosx.html" target="_blank">XAMPP 1.7.3</a> su mac questo file si trova in &#8220;/Applications/XAMPP/xamppfiles/bin&#8221;.</p>
<p>Lanciando la build del driver ottengo errori dovuti alla mancanza degli headers di mysql, errore che avevo già riscontrato nell&#8217;installazione di Imagick su XAMPP per Mac, vado per cui diretto sul sito di <a title="XAMPP 1.7.3 per Mac" href="http://www.apachefriends.org/it/xampp-macosx.html" target="_blank">XAMPP 1.7.3</a>, scarico il <em>development package</em> e lo installo.</p>
<p>Sperando nella buona sorte rilancio per l&#8217;ennesima volta la build di mysql-python e incappo nell&#8217;ennesimo errore. Questa volta sembra che sia dovuto ad una errata versione di XCode, ma leggendo più approfonditamente noto che il problema è dovuto al mancato supporto power-pc (ppc) a partire da XCode 4. Per risolvere questo ennesimo problema si deve editare il famoso <em>mysql_config</em> (in &#8220;/Applications/XAMPP/xamppfiles/bin&#8221; per chi usa XAMPP) nel seguente modo.</p>
<p>Alla riga 97 sostituite la versione minima di mac osx, io ho modificato da 10.4 a 10.6 (vedete voi), la mia riga ora è così:</p>
<pre class="brush: bash; title: ; notranslate">ldflags='-L/Applications/XAMPP/xamppfiles/lib -I/Applications/XAMPP/xamppfiles/include -mmacosx-version-min=10.6 '</pre>
<p>Alla riga 122 riportate la versione di mac appena modificata e inoltre eliminate la voce -arch ppc, la mia riga ora si presenta così:</p>
<pre class="brush: bash; title: ; notranslate">cflags=&quot;-I$pkgincludedir  -I/Applications/XAMPP/xamppfiles/include -L/Applications/XAMPP/xamppfiles/lib -mmacosx-version-min=10.6 -arch i386 -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ -DIGNORE_SIGHUP_SIGQUIT  -DDONT_DECLARE_CXA_PURE_VIRTUAL &quot; #note: end space!</pre>
<p>A questo punto lanciate la build e per magia arriverà fino al termine senza più errori. Potete quindi installare il pacchetto lanciando il comando:</p>
<pre class="brush: python; title: ; notranslate">sudo python setup.py install</pre>
<p>A questo punto django sarà tornato alla normalità (a meno che voi utilizzaste le python image library, PIL, per cui dovrete reinstallare anche quelle, ma io non ho riscontrato problemi nel farlo).</p><p>The post <a href="https://blog.davideferrero.com/2011/07/installare-django-1-3-mac-os-x-10-7-lion-xampp-1-7-3/">Installare Django 1.3 su Mac OS X 10.7 Lion e XAMPP 1.7.3</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://blog.davideferrero.com/2011/07/installare-django-1-3-mac-os-x-10-7-lion-xampp-1-7-3/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Installare Ubuntu Server 10.04 LTS con RAID 10 e LVM</title>
		<link>https://blog.davideferrero.com/2011/05/installare-ubuntu-server-10-04-lts-con-raid-10-e-lvm/</link>
					<comments>https://blog.davideferrero.com/2011/05/installare-ubuntu-server-10-04-lts-con-raid-10-e-lvm/#comments</comments>
		
		<dc:creator><![CDATA[davide]]></dc:creator>
		<pubDate>Mon, 02 May 2011 05:00:05 +0000</pubDate>
				<category><![CDATA[HowTo]]></category>
		<category><![CDATA[Informatica]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Ubuntu 10.04]]></category>
		<category><![CDATA[Ubuntu Server]]></category>
		<category><![CDATA[Ubuntu Server 10.04 LTS]]></category>
		<guid isPermaLink="false">http://blog.davideferrero.com/?p=550</guid>

					<description><![CDATA[<p>Eccomi qua! Dopo un po&#8217; di tempo con poche &#8220;scoperte&#8221; interessanti, oggi ritorno con un articolo che riguarda i server. Ovviamente quando parlo di server, parlo di linux e ancora più nello specifico di Ubuntu. Ultimamente per andare sul sicuro mi sono abituato ad utilizzare solo più le versioni LTS ossia le Long Term Support, [&#8230;]</p>
<p>The post <a href="https://blog.davideferrero.com/2011/05/installare-ubuntu-server-10-04-lts-con-raid-10-e-lvm/">Installare Ubuntu Server 10.04 LTS con RAID 10 e LVM</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>Eccomi qua! Dopo un po&#8217; di tempo con poche &#8220;scoperte&#8221; interessanti, oggi ritorno con un articolo che riguarda i server.</p>
<p>Ovviamente quando parlo di server, parlo di linux e ancora più nello specifico di <a title="Ubuntu Server" href="http://www.ubuntu.com/business/server/overview" target="_blank">Ubuntu</a>.</p>
<p>Ultimamente per andare sul sicuro mi sono abituato ad utilizzare solo più le versioni LTS ossia le Long Term Support, le versioni supportate per 3 anni, decisamente molto più stabili rispetto alle altre.</p>
<p>Quando si installa un server generalmente si ha a che fare con la necessità di mantenere il più possibile al sicuro i dati che vi verranno salvati e per fare ciò è buona norma gestire lo spazio a propria disposizione con il <a title="RAID" href="http://it.wikipedia.org/wiki/RAID" target="_blank">RAID</a> ossiamo un sistema di replica delle informazioni in tempo reale che tenta di ridurre al minimo le possibilità di perdita di dati (ridurre, non eliminare, ne ho le prove ;-) ).</p>
<p>L&#8217;installazione di Ubuntu consente di creare un RAID software nel caso in cui il server che stiamo preparando non abbia un sistema di RAID hardware.</p>
<p>Tralasciamo la discussione sulla scelta del RAID, per quello che ho potuto provare sulla mia pelle in genere è sempre meglio un RAID 0 o un RAID 1 o meglio ancora un RAID 1+0 detto anche RAID 10 perchè a differenza dell&#8217;alternativo RAID 5 lascia i dati in chiaro e quindi leggibili in qualsiasi momento, anche collegandolo su un&#8217;altra macchina (in caso di problemi). Detto ciò, veniamo a come preparare le partizioni per costruire il RAID.</p>
<p>Prendendo l&#8217;esempio di 2 dischi da 500 Gb vi conviene creare due partizioni primarie per ciascun disco (scegliete la voce &#8220;partizionamento manuale&#8221;): una dimensionata il doppio della ram presente sul server, e una con lo spazio rimanente. Ripetete la stessa cosa con le altre due partizioni dell&#8217;altro disco. Per ogni partizione alla voce &#8220;usare come&#8221; dobbiamo ricordarci di impostare &#8220;volume per il raid&#8221;. Fatto ciò possiamo terminare il partizionamento e configurare gli array raid tramite l&#8217;apposito menu, scegliendo il raid desiderato e settando quanti dischi usare per il raid (2) e quanti dischi di spare(0).</p>
<p>Come detto dobbiamo configurare due array, uno per la swap e uno per il sistema vero e proprio. Per il primo array scegliamo i due volumi a cui abbiamo assegnato il doppio della dimensione della ram, confermiamo e passiamo alla configurazione del secondo array con i restanti due volumi.</p>
<p>Finita la configurazione dei due array del raid possiamo terminare l&#8217;operazione e scrivere le modifiche.</p>
<p>Quando apparirà nuovamente la schermata con le tabelle delle partizioni potremo notare che sono state aggiunte due voci all&#8217;elenco, ossia quelle corrispondenti ai due arrays. A questo punto possiamo creare due partizioni (una per array) e impostare la voce &#8220;usare come&#8221; su &#8220;volume per LVM&#8221;.</p>
<p>L&#8217;<a title="Logical Volume Manager" href="http://it.wikipedia.org/wiki/Gestore_logico_dei_volumi" target="_blank">LVM</a> è un gestore dei volumi logici, ossia consente di creare dei volumi &#8220;estendibili&#8221; in qualsiasi momento. Infatti smontando i volumi si possono aumentare le loro dimensioni senza dover formattare e senza subire perdite di dati, e addiritture si possono raggruppare in un unico volume più dischi (anche aggiunti in un secondo momento). Un po&#8217; quello che si può fare tramite l&#8217;ormai conosciutissimo <a title="GParted" href="http://gparted.sourceforge.net/" target="_blank">GParted</a> in Ubuntu desktop.</p>
<p>Tornando all&#8217;installazione del nostro ubuntu server, una volta impostate le nostre partizioni come volumi per LVM possiamo procedere alla creazione dei due volumi logici, come già detto uno per lo swap e uno per il sistema. Una volta confermata la creazione dei due volumi logici (dovrete assegnare un nome ai volumi da creare, ad esempio &#8220;swap&#8221; e &#8220;srv&#8221;) nella tabelle delle partizioni troveremo altre due voci, rappresentati i due nuovi volumi appena creati.</p>
<p>A questo punto possiamo procedere alla creazione delle partizioni da far usare all&#8217;installazione di Ubuntu: una da impostare come &#8220;volume swap&#8221; e l&#8217;altra da impostare con ext4 (o ext3 per i più tradizionalisti :-P ). Ovviamente la partizione formattata con ext4 dovrà avere come punto di mount &#8220;/&#8221; (root). Confermate queste modifiche l&#8217;installazione procederà a gonfie vele, e in pochi minuti il vostro server sarà pronto per l&#8217;uso! :-)</p><p>The post <a href="https://blog.davideferrero.com/2011/05/installare-ubuntu-server-10-04-lts-con-raid-10-e-lvm/">Installare Ubuntu Server 10.04 LTS con RAID 10 e LVM</a> first appeared on <a href="https://blog.davideferrero.com">Davide Ferrero</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://blog.davideferrero.com/2011/05/installare-ubuntu-server-10-04-lts-con-raid-10-e-lvm/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
	</channel>
</rss>
