Els vídeos de la deSymfony2012

Des de fa uns dies ja estan penjats els vídeos de les conferències de la deSymfony 2012 celebrada a Castelló a mitjans de juny passat.

Recordem que Symfony és un framework MVC (i algunacosa més) per a desenvolupar aplicacions amb php.

La deSymfony és la “La conferencia hispana más importante sobre Symfony y la segunda a nivel mundial.”

Molt remarcable la presència i la presentació de Fabien Potencier, el creador de Symfony i CEO de SensioLabs.

Font: http://desymfony.com/videos. Els enllaços porten a les respectives pàgines de les presentacions a deSymfony.com, on es pot trobar el ppt de la presentació i el vídeo corresponent al YouTube.

Vídeos de la 1ra jornada,  divendres 15 de juny

Vídeos de la 2na jornada,  dissabte 16 de juny

Anuncis

Apunts d’HTML5

HTML5 és més que un llenguatge d’etiquetes. És el resultat de la convergència dels esforços del WWW Consortium i el WHATWG per a fer evolucionar l’HTML. Amb HTML5 podem parlar pròpiament de “programació”. A la vegada, es manté la compatibilitat cap enrere, Tot HTML previ a HTML5 “és també” HTML5. Ara bé, si fem servir les noves etiquetes, fulls d’estil i les noves APIs de javascript podrem arribar molt lluny.

Una demostració del que es pot arribar a fer amb HTML5 és aquest Mario Bros. El codi es pot descarregar. Només cal registrar-se gratuitament a codeproject.com.

Què ens proporciona HTML5? Sense ser exhaustius:

– Noves etiquetes amb nova semàntica per a organitzar millor la presentació de la informació
– Noves etiquetes per a afegir àudio i vídeo a les pàgines sense haver de dependre de plugins de terceres parts.
– Canvas, que ens permet dibuixar en 2D i 3D generant imatges tipus bitmap.
– SVG Scalable Vector Graphics. Per a generar imatges vectorials.
– Un mecanisme nou i consistent entre els diferents browsers per a emmagatzemar dades locals (Local Storage, més enllà de les cookies).
– Nous tipus de camps als formularis HTML amb, això és important, validació pel propi navegador.
– Geolocalització.
– Microdata (una eina per al posicionament a Internet).
– aplicacions offline.
– Base de dades SQL local
– …

Compatibilitat
HTML5 no està especificat del tot. No tots els navegadors dels diferents dispositius suporten HTML5, només els més moderns. No tots els navegadors moderns suporten “tot” l’HTML5. O el suporten exactament igual. En definitiva, res de nou.

Tanmateix, és una bona idea avançar poc a poc en la migració a HTML5. Tot l’HTML anterior a HTML5 és, també HTML5, per tant, la transició a HTML5 “heavy” es pot encetar gradualment.

Abans d’utilitzar una característica d’HTML5 caldrà determinar si està disponible al navegador de l’usuari. En entorns controlats, com intranets, on el navegador de l’usuari pot estar especificat, aquesta pot ser una tasca senzilla. En entorns més oberts una aproximació útil és fer servir llibreries javascript per a determinar les prestacions del navegador. Una de recomanada sovint als diferents manuals és la llibreria opensource Modernizr.

En general, fent servir Modernizr, seguirem el següent esquema:

if (Modernizr.CaracterísticaHTML5) {
    // puc fer servir HTML5
} else {
    // no puc fer servir HTML5
}

Anem a repassar amb més detall algunes opcions:

Noves etiquetes (algunes)
Noves etiquetes per a organitzar la informació, section, article… N’hi han moltes més!

<section>
una secció
<aside> 
informació addicional
</aside>
<header>la capcelera</header>
<article>un article</article>
<footer>el peu</footer>
</section>

Aquestes etiquetes permeten organitzar la informació de forma més propera a com s’està presentant habitualment. Un dels criteri en el desenvolupament d’HTML5 és “estandaritzar” allò que s’està fent. O si es vol, de regular les bones pràctiques. És dir, no s’inventa res si no cal, més aviat, s’afina. Les etiquetes section, article… anteriors es podien trobar abans d’HTML5 com els noms més habituals en DIVs, com va descobrir Google en analitzar milers de pàgines, fent les funcions d’organització que justament ara assumeixen.

CSS
Aquestes etiquetes no tenen, a priori, una representació gràfica predeterminada i això ens porta a l’altre element fonamental de’HTML5: el CSS3 (CSS level 3, acrtualment en desenvolupament).

A HTML5 es considera una mala pràctica (en realitat, des d’abans d’HTML5 que es considera una mala pràctica) l’ús dels atributs modificadors de la presentació a les etiquetes. Totes les característiques de presentació haurien d’anar a fulls d’estil CSS.

Etiquetes per a audio i video
Finalment, l’audio i el video es podran reproduir de forma nativa sense que calguin plugins (és la fi de Flash?). En realitat, la reproducció d’àudio i vídeo nativa dependrà dels còdecs disponibles. A més, no tots els navegadors suporten les etiquetes audio i video. Tot plegat, la següent estructura es pot utilitzar com a punt de partida:

Audio:

<audio controls>
    <source src="audio.ogg" type="audio/ogg">
    <source src="audio.mp3" type="audio/mpeg">
    <a href="http://player.swf?soundFile=audio.mp3">
    http://player.swf?soundFile=audio.mp3</a>
</audio>

L’explicació és la següent: la llista de sources ens permet proporcionar l’audio en diferents formats, amb l’esperança que algun d’ells serà nadiu al navegador dels usuaris (ogg és nadiu a firefox i chrome). El navegador reproduirà el primer de la llista per al que disposi de còdecs. Atenció, doncs, a l’ordre! En cas que el navegador no suporti l’etiqueta audio, aleshores, encara es podrà fer servir el plugin de flash. Si tampoc això funciona, es podrà descarregar el fitxer d’àudio amb un enllaç.

Vídeo:
És simètric a l’anterior:

<video controls 
width="360" height="240"
       poster="poster.jpg">
    <source src="video.ogv" type="video/ogg">
    <source src="video.mp4" type="video/mp4">
    <a href="http://player.swf?file=video.mp4">
    http://player.swf?file=video.mp4</a>
</video>

Com a comentari general, vàlid per a audio i video, indicar que cal especificar correctament els Content-type dels àudios i els vídeos. No A més, cal que els Content-types estiguin disponibles a la llista de Content-types del servidor web que serveis les pàgines.

Canvas
Canvas ens permet dibuixar. Això que sembla tan poca cosa, senzillament no es podia fer abans de forma fàcil. Ara es pot. l’etiqueta canvas determina una regió rectangular en la que es podrà, mitjançant javascript, dibuixar línies, rectangles, corbes… pintar de colors, amb diferents tipus de pinzells, aplicar transformacions…
Canvas és, en ell mateix, tot un món. Vegem-ne un petit exemple:

<!DOCTYPE html>
<html>
<head><title>Canvas</title>
<script>
function Pinta() {
    alert(Math.PI);
    var canvas = document.getElementById('idCanvas');
    var ctx = canvas.getContext('2d');
    ctx.beginPath();
    ctx.moveTo(10,120);

    for(var x=10; x<=310; ++x) {
        y = 100*Math.sin(2*Math.PI*(x - 10)/300);
        ctx.lineTo(x, 120 - y);
    }
    ctx.stroke();
}
</script>
</head>
<body onload="Pinta()">

<canvas id="idCanvas" width="320" height="240">
</canvas>
</body>
</html>

Ens dibuixa la bonica corba sinusoïdal.

 

SVG
No només es poden crear programàticament imatges bitmap o raster. Tambés es poden crear imatges vectorials amb SVG. SVG ja és un vell conegut de diferents browser, com el Firefox, però ara passa a formar part de “l’especificació” d’HTML5. Per a il·lustrar, aquí mostro el que podria ser l’esquelet d’un petit joc:  proveu a fer click al cercle roig que batega i es mou ràpidament per la regió rectangular. Vet aquí una combinació de SVG i JavaScript.

Aquesta animació ha estat del tipus programàtic basada en setInterval de JavaScript, però és possible animar els objecte SVG de forma declarativa, amb l’element “animate”.

<!DOCTYPE html>
<html>
<head>
<meta charset="latin-1" />
<title>svg</title>
<script>
var xx=240;
var yy=160;
var rr=10;
var ix=1; var iy=1; var ir=1;
var obj=null;
var objClicks = null;
var totalClicks = 0;
function init() {
  obj = document.getElementById("idCercle");
  objClicks = document.getElementById("idScoring");
  setInterval("anima()",10);
}

function anima() {
  obj.setAttribute("cx", xx);
  obj.setAttribute("cy", yy);
  obj.setAttribute("r",rr);

  xx += ix; yy += iy; rr += ir;

  if (((xx + rr) > 480) || ((xx - rr) < 0)) {ix = -ix};
  if (((yy + rr) > 320) || ((yy - rr) < 0)) {iy = -iy};
  if ((rr > 20) || (rr < 5)) {ir = -ir};

  return true;
}

function ImA(whatiam) {
      ++totalClicks;
	  objClicks.innerHTML="jo soc un " + whatiam + "; total de clicks: " + totalClicks;
	  return true;
}
</script>
</head>
<body onload="init()">
<svg height="320" width="480" id="idSvgCanvas">
    <circle fill="#ff0000" onclick="ImA('cercle');" id="idCercle">
	</circle>
</svg>
<div id="idScoring">Click me!</div>
</body>
</html>

 

Nous tipus de camps de formulari

HTML5 afegeix nous camps de formulari. Pel que fa a la compatibilitat amb navegadors no HTML5, aquests representaran als nous camps com camps de text. De fet, aquest serà el comportament dels navegadors que suporten HTML5 però que no tenen un comportament específics per a aquests nous tipus.

Dit d’una altra forma, si preveiem que un camp d’un formulari s’adapta a algun dels nous tipus, és interessant fer servir el nou tipus, encara que el navegador no suporti HTML5 perquè, de totes formes, els seguirà presentant com una caixa de text.
En un futur aquests nous camps estaran.

Actualment ja hi han alguns navegadors que fan un tractament especial i validació “nadiua” per a determinats camps.

En el cas de Google Chrome, de moment hi ha representació gràfica especial per als type=”number”, type=”range” i s’ha afegit l’atribut “placeholder” en els input type de tipus text.

<!DOCTYPE html>
<html>
<head><title>Form</title>
</head>
<body ">
<form id="idForm">
data: <input type="date" name="data" placeholder="data"/><br />
hora: <input type="time" name="hora" placeholder="hora"/><br />
placeholder: <input type="text" placeholder="prova placeholder" name="texts" /><br />
email: <input type="email" name="email" placeholder="email" /><br />
url: <input type="url" name="url" placeholder="url"/><br />
Nombre: <input type="number" min="0" max="100" step="5" value="50" /><br />
Rang: <input type="range" min="0" max="100" step="5" value="50" /><br />
cerca: <input type="search" name="cerca" placeholder="cerca"><br />
color: <input type="color" name="color" placeholder="color"><br />
</form>
</body>
</html>

El codi anterior es presenta de la següent forma amb Google Chrome:

Geolocalització
Si està disponible en el navegador del dispositiu mòbil de l’usuari la geolocalització, geolocation, permet, si l’usuari dona el seu permís, que els llocs puguin conèixer l’ubicació del dispositiu del client. Depenent del dispositiu aquesta ubicació es determina de forma molt precisa, via gps, o no tant, per triangulació entre repetidors de telefonia, o de forma més burda, per rang d’IP del proveïdor. A priori, doncs hi ha indeterminació pel que fa a la precisió en la geolocalització, i en el temps de resposta. És més costosa, però molt més precisa, una localització per GPS que una localització per IP, que és immediata, però que pot tenir una “precisió” d’un radi de centenars de quilòmetres.

Un exemple de localització el tenim en el següent codi:

<!DOCTYPE html>
<html>
<head>
<meta charset="latin-1" />
<title>geoloc</title>
<script type="text/javascript">
function geoloc() {
	if (navigator.geolocation) {
	  var timeoutVal = 10 * 1000 * 1000;
	  navigator.geolocation.getCurrentPosition(
	    displayPosition, 
	    displayError,
	    { enableHighAccuracy: true, timeout: timeoutVal, maximumAge: 0 }
	  );
	}
	else {
	  alert("Aquest navegador no suporta la geolocalització");
	}
}

function displayPosition(position) {
  var lLat = position.coords.latitude; 
  var lLong = position.coords.longitude
  var sText= "<b>Latitud:</b> " + lLat + 
             ", <b>Longitud:</b> " + lLong;
  document.getElementById("idPos").innerHTML = sText;
  var sImgSrc = "http://maps.google.com/maps/api/staticmap?" +
               "center=" + lLat + "," + lLong + "&zoom=14&size=512x512&maptype=roadmap&" + 
               "markers=color:blue%7Clabel:S%7C" + lLat + "," + lLong + "&sensor=false";
  document.getElementById("idImg").src = sImgSrc;
}

function displayError(error) {
  var errors = { 
    1: 'Permission denied',
    2: 'Position unavailable',
    3: 'Request timeout'
  };
  document.getElementById("idPos").innerHTML = "Error: " + errors[error.code];
}
</script>
</head>
<body onload="geoloc()" onunload="GUnload()">
Geolocalització.<br />
<div id="idPos">Calculant posició...</div>
<img id="idImg" src="" height="512" width="512" "alt="la meva ubicació"/>
</body>
</html>

Al provar la pàgina anterior al Mozilla Firefox, primer de tot observo que em demana permís:

Li en dono, i em mostra la meva posició.

Val a dir que no ha estat gens precís! Estic fent aquest experiment amb l’ordinador de sobretaula i, evidentment, la localització va per rang d’IP. Encara bo que ha trobat que és Barcelona! Evidentment, la potència de la geolocalització apareix quan la fem servir sobre dispositius mòbils que permeten una ubicació precisa.

Microdata
Les microdata permet afegir semàntica a les pàgines html. Això que sona molt críptic, i que segurament ho és X)), es pot traduir a “un sistema per afegir informació útil a la nostra pàgina web per a que cercadors i indexadors, o sigui Google, la trobin més interessant i la facin sortir més amunt o més destacada en les cerques”.

Microdata afegeix la semàntica mitjançant uns atributs (itemscope, itemtype, itemid, itemprop, itemref) en les etiquetes de l’HTML.

Aquests atributs permeten identificar peces del contingut de la pàgina marcat per etiquetes HTML com valors de propietats definides en un vocabulari.

Els vocabularis són petits i estan relacionats amb un camp semàntic.

Les Microdata utilitzen vocabularis per a definir la semàntica que es volo afegir. Tothom pot crear els vocabularis que vulgui per al camp semàntic que li interessi, però ja n’hi han de fets. I els podeu examinar a http://www.data-vocabulary.org/

Per exemple, per al camp semàntic “persona” podem trobar el següent vocabulari a http://www.data-vocabulary.org/Person/

Property          Description
--------          ----------- 
name (fn)         Name
nickname          Nickname
photo             An image link
title             The person's title (for example, Financial Manager)
role              The person's role (for example, Accountant)
url               Link to a web page, such as the person's home page
                  affiliation (org) The name of an organization with
                  which the person is associated (for example, an
                  employer). If fn and org have the exact same value,
                  Google will interpret the information as referring
                  to a business or organization, not a person.
friend	          Identifies a social relationship between the person
                  described and another person.
contact	          Identifies a social relationship between the person
                  described and another person.
acquaintance	  Identifies a social relationship between the person
                  described and another person.
address (adr)	  The location of the person. Can have the
                  subproperties 
                       street-address, 
                       locality, 
                       region, 
                       postal-code, 
                       and country-name.

Com funciona? el següent exemple esta extret de la Wikipedia

HTML original

<section> Hello, my name is John Doe, 
I am a graduate research assistant at 
the University of Dreams. 

My friends call me Johnny. 
You can visit my homepage at 
<a href="http://www.JohnnyD.com">www.JohnnyD.com</a>. 
I live at 1234 Peach Drive Warner Robins, Georgia.
</section>

Aquest HTML se li pot afegir semàntica, és dir, significat per als cercadors, de la següent forma:

<section itemscope itemtype="http://data-vocabulary.org/Person"> 
        Hello, my name is 
        <span itemprop="name">John Doe</span>, 
        I am a 
        <span itemprop="title">graduate research assistant</span> 
        at the 
        <span itemprop="affiliation">University of Dreams</span>. 
        My friends call me 
        <span itemprop="nickname">Johnny</span>. 
        You can visit my homepage at 
        <a href="http://www.JohnnyD.com" itemprop="url">www.JohnnyD.com</a>. 
        <section itemprop="address" itemscope itemtype="http://data-vocabulary.org/Address">
                I live at 
                <span itemprop="street-address">1234 Peach Drive</span> 
                <span itemprop="locality">Warner Robins</span>
                , 
                <span itemprop="region">Georgia</span>.
        </section>
</section>

Aquest tros de codi HTML5 (noteu l’us de l’etiqueta section) és interpretat per Google de la següent forma (es pot provar el resultats d’afegir Microdata a les pàgines amb el Google’s Rich Snippet Testing Tool.)

I una advertència: que Google pugui interpretar la Microdata NO vol dir, repeteixo, NO vol dir, que forçosament en millori el posicionament.

Database Storage
L’especificació del “Database storage” permet afegir una base de dades SQL local al navegador de l’usuari, per a utilitzar-la localment i com a magatzem persistent.
L’especificació no diu quina BD ha de ser, però almenys Chrome (també Chromium i Android) i Opera estan implementant SQLite i són les úniques implementacions a dia d’avui.

La tria d’SQLite no és casual. Aquesta eficient i potent BD opensource forma part de projectes com FireFox i Chrome des de fa molt de temps. La meva opinió és que disposar d’aquesta BD formant part del nucli del navegador i no posar-la a disposició del usuari era una provocació.

Que la BD triada a les implementacions disponibles sigui SQLlite permet entre d’altres coses, que la puguem examinar (i operar amb ella) fent us d’eines com SQLIteman. Això sí, cal saber on buscar: En el cas del Linux Ubuntu 12.04 que tinc instal·lat i amb el que faig els meus experiments, resulta que, per a Chrome, les bases de dades SQLite es troben, ben amagades, a /home/usuari/.config/google-chrome/Default/databases/file__0 i es van numerant. Amb una inspecció de la carpeta no es poden identificar per nom.

Cal repetir, però, que Database Storage no està present a tots els navegadors que suporten HTML5.

Tanmateix, és temptador disposar d’una BD SQL local.

El següent és un exemple d’agenda de telefons que vaig trobar a Internet (lamentablement, no em vaig guardar l’enllaç) i que he adaptat.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="latin-1" />
        <title>SQL Storage</title>
            
        <script>        
        var sCreate = "CREATE TABLE IF NOT EXISTS Agenda (id INTEGER PRIMARY KEY AUTOINCREMENT, Nom TEXT, cognom TEXT, telefon TEXT)";
        var sSelectAll = "SELECT * FROM Agenda";
        var sInsert = "INSERT INTO Agenda (Nom, cognom, telefon) VALUES (?, ?, ?)";
        var sUpdate = "UPDATE Agenda SET Nom = ?, cognom = ?, telefon = ? WHERE id = ?";
        var sDelete = "DELETE FROM Agenda WHERE id=?";
        var sDrop = "DROP TABLE Agenda";
        var db, dataset;        
        var resultats, id, Nom, cognom, telefon;
        
        function inicialitza() {
            resultats = document.getElementById('resultats');
            id = document.getElementById('id');
            Nom = document.getElementById('Nom');     
            cognom = document.getElementById('cognom'); 
            telefon = document.getElementById('telefon');
            db = openDatabase("AgendaTelefons.db", "1.0", "Agenda de Telefons", 200000);
            crearTaula();
        }
        
        function onError(tx, error) {
            alert(error.message);
        }
        
        function mostrarFiles() {
            resultats.innerHTML = '';
            db.transaction(function(tx) {
                tx.executeSql(sSelectAll, [], function(tx, result) {
                    dataset = result.rows;
                    for (var i = 0, item = null; i < dataset.length; i++) {
                        item = dataset.item(i);
                        resultats.innerHTML +=
                        '<li>' + item['cognom'] + ' , ' + item['Nom'] + 
                        ' <a href="#" onclick="carregarFila('+i+')">modificar</a>  ' + 
                        '<a href="#" onclick="esborrarFila('+item['id']+')">esborrar</a></li>';
                    }
                });
            });
        }
        
        function crearTaula() {
            db.transaction(function(tx) {
                tx.executeSql(sCreate, [], mostrarFiles, onError);
            });
        }
        
        function afegirFila() {
            db.transaction(function(tx) {
                tx.executeSql(sInsert, [Nom.value, cognom.value, telefon.value], carregar_i_reset, onError);
            });
        }
        
        function carregarFila(i) {
            var item = dataset.item(i);
            Nom.value = item['Nom'];
            cognom.value = item['cognom'];
            telefon.value = item['telefon'];
            id.value = item['id'];
        }
        
        function actualitzarFila() {
            db.transaction(function(tx) {
                tx.executeSql(sUpdate, 
                          [Nom.value, cognom.value, telefon.value, id.value], 
                          carregar_i_reset, 
                          onError);
            });
        }
        
        function esborrarFila(id) {
            db.transaction(function(tx) {
                tx.executeSql(sDelete, [id], mostrarFiles, onError);
            });
            netejaFormulari();
        }
        
        function esborrarTaula() {
            db.transaction(function(tx) {
                tx.executeSql(sDrop, [], mostrarFiles, onError);
            });
            netejaFormulari();
        }
        
        function carregar_i_reset() {
            netejaFormulari();
            mostrarFiles();
        }
        
        function netejaFormulari() {
            Nom.value = '';
            cognom.value = '';
            telefon.value = '';
            id.value = '';
        }
        </script>
    </head>
    
    <body onload="inicialitza();">   
        <br/><br/>
        <div align="center">
            <input type="hidden" id="id"/>
            Nom:<input type="text" id="Nom"/><br/>
            Cognom:<input type="text" id="cognom"/><br/>
            Telefon: <input type="text" id="telefon"/><br/>
            <button onClick="netejaFormulari()">Neteja Formulari</button>
            <button onClick="actualitzarFila()">Actualitzar</button>
            <button onClick="afegirFila()">Afegir</button>
            <button onClick="esborrarTaula()">Esborrar taula</button>
            <div id="resultats"> </div>
        </div>
    </body>
</html>

Local Storage
Local Storage és una alternativa als Cookies. És dir, és un mecanisme senzill i consistent entre els navegadors per a emmagatzemar parelles nom-valor de forma persistent (o sigui que entre sessions mantenim la informació).

Aquesta característica l’implementen tots els navegadors que suporten HTML5, des de Internet Explorer fins a Safari, passant pels Chrome, Android, Opera o FireFox. Com a curiositat, en el cas de FireFox resulta que la tecnologia amb que s’implementa Local Storage és, ves quina cosa, SQLite.

LocalStorage proporciona una API senzilla:
getItem(clau),
setItem(clau, valor),
removeItem(clau),
lenght: número de clausdeter
key(index): clau i-èssima

Els dos últims ens permeten implementar un iterador. Anem a repetir l’agenda de telefons fent servir LocalStorage:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="latin-1" />
        <title>Local Storage</title>
            
        <script>              
        var resultats, NomCognom, telefon;
        
        function inicialitza() {
            resultats = document.getElementById('resultats');
            NomCognom = document.getElementById('NomCognom');     
            telefon = document.getElementById('telefon');
            mostrarFiles();
        }
        
        
        function mostrarFiles() {
            resultats.innerHTML = '';
            for (var i = 0; i < localStorage.length; i++) {
            	item = localStorage.key(i);
               resultats.innerHTML +=
               '<li>' + item + "-" + localStorage[item] + 
               ' <a href="#" onclick="carregarFila(\''+ item +'\')">modificar</a>  ' + 
               '<a href="#" onclick="esborrarFila(\''+ item + '\')">esborrar</a></li>';
            }
        }
        
        
        function afegirFila() {
            localStorage[NomCognom.value] = telefon.value;
            mostrarFiles();            
        }
        
        
        function carregarFila(item) {
            NomCognom.value = item;
            telefon.value = localStorage[item];
        }
        
        
        function esborrarFila(item) {
            localStorage.removeItem(item);
            netejaFormulari();
        }
        
        
        function netejaFormulari() {
            NomCognom.value = '';
            telefon.value = '';
            mostrarFiles();
        }
        </script>
    </head>
    
    <body onload="inicialitza();">   
        <br/><br/>
        <div align="center">
            Nom i cognom: <input type="text" id="NomCognom"/><br/>
            Telefon: <input type="text" id="telefon"/><br/>
            <button onClick="netejaFormulari()">Neteja Formulari</button>
            <button onClick="afegirFila()">Afegir - Actualitzar</button>
            <div id="resultats"> </div>
        </div>
    </body>
</html>

I recordem que amb Chrome, podem repassar el contingut del localStorage (amb F12, eines de desenvolupador, a la pestanya resources).

Aplicacions Offline
Amb HTML5 podem fer aplicacions. Les aplicacions amb HTML5 són aplicacions web, és dir, connectades. Aplicacions que viuen a Internet. Tanmateix, característiques com Local Storage o Database Storage ens obren la possibilitat a desenvolupar aplicacions que puguin treballar desconnectades.

Les aplicacions desconnectades es descarregaran total o parcialment al nostre dispositiu, i seran funcionals quan el dispositiu no estigui connectat a Internet, és dir, físicament estaran al nostre dispositiu.

Fer una aplicació offline és tan senzill com afegir-li un fitxer de manifest de caché a una aplicació HTML5 “normal”, i que les pàgines de l’aplicació el declarin a l’etiqueta HTML

<html manifest="/cache.manifest">

El manifest té un content-type específic: “text/cache-manifest”. Cal assegurar que el servidor web serveix el content type correctament.

Què hi posarem en aquest manifest? ni més ni menys que la llista de pàgines i recursos que formaran l’aplicació offline. Un cop el navegador llegeixi el manifest procedirà a descarregar els diferents components. Per exemple:

CACHE MANIFEST
/index.html
/estils.css
/scripts.js
/imatge01.jpg
/imatge02.jpg
/imatge03.jpg

La primera línia ha de ser “CACHE MANIFEST”.

Tanmateix, també podem voler que hi hagin pàgines o recursos que explícitament no es descarreguin mai. Aleshores podem distingir entre recursos a la xarxa, i recursos a la caché

   
CACHE MANIFEST
NETWORK:
/comptador.php
CACHE:
/index.html
/estils.css
/scripts.js
/imatge01.jpg
/imatge02.jpg
/imatge03.jpg

Els recursos a la secció NETWORK no seran descarregats.

A més, por passar l’aplicació web hi hagin recursos que no estiguin definits ni a NETWORK, ni a CACHE. En aquest cas podem tenir una secció FALLBACK per a tractar aquests casos especials.

Per a saber-ne molt més
Hi han molts i molt bons manuals d’HTML5. I alguns d’ells es poden trobar lliures a Internet. En particular, jo m’he llegit, o m’estic llegint els següents:

http://diveintohtml5.info/. Aquesta web és la versió online i lliure del llibre “HTML5. Up and Running” de Mark Pilgrim, publicat per O’Reilly.

Un altre llibre interessant: Pro HTML5 Programming, publicat per Apress

Aquest és molt fàcil de llegir, és curtet i va al gra: HTML5 for Web Designers, publicat per “A Book Apart”.

Una cerca a la web us proporcionarà molts resultats. Els llibres que he citat són, simplement, alguns que he llegit i que, per tant, amb veig amb cor de recomanar.

A més, crec que és molt útil disposar des “xuletaris” o cheat sheets. Aquests estan molt bé:

HTML 5: http://webdesign.about.com/b/2012/05/01/html5-cheat-sheet.htm

Encara un altre d’HTML5: http://www.smashingmagazine.com/2009/07/06/html-5-cheat-sheet-pdf/

Canvas: http://www.nihilogic.dk/labs/canvas_sheet/

Un bon xuletari de CSS també ajuda
CSS: http://coding.smashingmagazine.com/2009/07/13/css-3-cheat-sheet-pdf/

En aquest enllaç, fins i tot fan una recopilació de cheat sheets de CSS.

Finalment, si voleu veure exemples d’HTML5 en acció,aquesta web en proporciona molts: http://html5demos.com/

Taules amb cantonades rodones (reprise)

En un post anterior vaig explicar com  fer caixes amb els cantons rodons amb HTML.

En aquella ocasió la solució es basava en taules HTML aplicant estils a etiquetes <table> <tr> i <td>.

En ocasions , un enfocament com l’anterior pot ser necessari, perquè hi han un munt de pàgines web que fan servir, o han fet servir, les taules per a maquetar-ne la presentació, i pot ser que ens calgui retocar-les.

Des de fa temps, però, la solució amb taules es considera inadequada. Les taules HTML només haurien de fer-se servir per presentar dades en format tabular, i formatar-les amb css.

Per a maquetar, la recomanació general és fer servir capes (etiquetes <div>). Per al cas concret de taules amb cantons rodons, vet aquí solucions possibles.

Si em cal crear els gràfics corresponents a les caixes amb els cantons rodons, faig servir la combinació de Inkscape i Gimp. Inkscape permet crear caixes amb cantons rodons, especificant mides i radis dels cantons,  aplicar diferents efectes i exportar les caixes a format png. Després, per retallar les diferents cantonades, les o tapes, o els costats, es pot fer servir el Gimp, per exemple.

OpenOffice.org/LibreOffice Draw també permet crear caixes amb els cantons rodons amb l’eina de dibuix caixa i fent, després Format-Posició i Mida i ajustant el radi a la pestanya Inclinació i Radi de la Cantonada. La pega de fer servir aquesta eina és que no disposa de la unitat “píxel”, d’us comú al disseny web. Si la fem servir segurament ens caldrà fer una conversió prèvia a les unitats de treball OOo/LO. Per exemple, fer servir punts, la conversió és 3pt aprox. igual a  4px.

El cas trivial és que coneixem d’antuvi la mida que tindrà la taula. En aquest cas, n’hi ha prou amb fer-servir la caixa de background d’un div:

<div class=”caixa”>Compte amb no sortir-se’n dels
marges pre-establerts.<br>
<ul>
  <li>ítem 1</li>
  <li>ítem 2</li>
  <li>ítem 3</li>
  <li>ítem 4</li>
  <li>ítem 5</li>
  <li>ítem 6</li>
  <li>ítem 7</li>
</ul>
</div>

i tindré la següent definició per a la class caixa:

.caixa {
  border-style: none;
  margin: 0px;
  padding: 5px;
  width: 401px;
  background-image: url(http://localhost/albert/prova01/img/quadre401x201px.gif);
  background-repeat: no-repeat;
  height: 201px;
  font-family: Arial,Helvetica,sans-serif;
  color: #000099;
  top: 0px;
  right: 0px;
  bottom: 0px;
  left: 0px;
}

On la imatge és aquesta:

Pot ser útil  crear caixes que es redimensionin automàticament:

Aquesta és una caixa que pot  créixer en vertical. Cal fer tres capes: una capa per la tapa superior, una capa central, i una capa per a la tapa inferior.

<div class=”topbox”>&nbsp;</div>

<div class=”midbox”>exemple de caixa que port créixer en
vertical. Només cal anar afegint text per veure com creix sense haver
de fer res més.<br>
</div>

<div class=”bottombox”>&nbsp;</div>

Les css corresponents:

.topbox {
  background-image: url(img/top-quadre301x12px.png);
  width: 301px;
  height: 12px;
  background-repeat: no-repeat;
}
.midbox {
  padding: 5px;
  background-image: url(img/bg-quadre301x1px.png);
  width: 301px;
  font-family: Arial,Helvetica,sans-serif;
  font-size: 25px;
  background-repeat: repeat-y;
}
.bottombox {
  width: 301px;
  background-repeat: no-repeat;
  background-image: url(img/bottom-quadre301x12px.png);
  height: 12px;

Les mides de les imatges han de coincidir amb les dels div.

Les imatges de les tapes superior i inferior:

i la imatge central que és d’1 pixel d’amplada i que aconsegueix emplenar la capa en vertical amb el background-repeat: repeat-y

 

De forma similar, es pot crear una caixa capaç d’adaptar-se, fins un tamany màxim, a divrerents llargades horitzontals. Em cal una tapa a l’esquerra, una capa central i la tapa de la dreta. Aleshores cal indicar que la imatge central ha de repetir-se en horitzontal.
Com cal posar les capes una a continuació de l’altre, cal indicar que “floten”:

<div class=”leftbox”>&nbsp;</div>

<div class=”midbox2″>exemple de caixa que pot créixer en
horitzontal fins un màxim de 900px. Cal vigilar perquè tindrà un màxim
de línies útils.<br>
</div>

<div class=”rightbox”>&nbsp;</div>

Els css corresponents són:

.leftbox {
  background-image: url(img/left-quadre12x151px.png);
  background-repeat: no-repeat;
  height: 151px;
  width: 12px;
  float: left;
}
.midbox2 {
  padding: 5px;
  background-repeat: repeat-x;
  float: left;
  font-family: Arial,Helvetica,sans-serif;
  background-image: url(img/bg-quadre1x151px.png);
  height: 151px;
  max-width: 900px;
  font-size: 40px;
}
.rightbox {
  background-image: url(img/right-quadre12x151px.png);
  background-repeat: no-repeat;
  width: 12px;
  height: 151px;
  float: left;
}

Les imatges són:

En aquest últim cas,  caldrà tenir en compte que les dimensions de la pantalla poden provocar que alguna capa passi a la fila inferior, desmuntant l’efecte de caixa. Es pot prendre la precaució d’agrupar les tres capes anteriors en una capa de dimensions suficients i que forçaria l’aparició de la barra d’scroll horitzontal si calgués.

Finalment, pot ser interessant disposar d’un mètode general per a fer caixes de mida ajustable.

El següent és una tècnica adaptada de http://www.neuroticweb.com/recursos/css-rounded-box/. Amb aquesta tècnica només cal fixar la mida horitzontal.

Com en els casos anteriors tindrem una tapa superior, una capa central i una capa de tapa inferior.  Però les tapes tindran, a més sengles capes addicionals per a fer cada una la cantonada dreta corresponent.

Vet aquí el codi. Podem ampliar el text o posar i treure <br> per veure’n els resultats.

<div class=”rbbox”>

    <div class=”rbltop”>
        <div class=”rbrtop”>&nbsp;</div>
    </div>

    <div class=”rbcontent”>
        <p>aquesta és una prova de caixa que s’adapta de forma<br>
        automàtica a la mida del seu contingut.<br>
        Adaptat de 

        <a href=”http://www.neuroticweb.com/recursos/css-rounded-box/”&gt;
        http://www.neuroticweb.com/recursos/css-rounded-box/</a></p&gt;
    </div>

    <div class=”rblbot”>
        <div class=”rbrbot”>&nbsp;</div>
    </div>
</div>

Els css són aquests:

.rbbox { background: url(img/rbbg.gif) repeat; width: 300px; margin: 0 100px; }
.rbltop { background: url(img/rbtl.gif) no-repeat top left; }
.rbrtop { background: url(img/rbtr.gif) no-repeat top right; }
.rblbot { background: url(img/rbbl.gif) no-repeat bottom left; }
.rbrbot { background: url(img/rbbr.gif) no-repeat bottom right; }
.rbcontent { margin: 5px 5px; }

I les imatges:

Finalment, dir que de tècniques per a fer cantonades rodones amb HTML i CSS  n’hi han moltes. A aquest enllaç (http://www.devwebpro.com/25-rounded-corners-techniques-with-css/) en podem trobar un bon grapat.

CSS Box model. quirks mode vs. w3c mode

Recentment he estat involucrat en la creació de pàgines web amb crossbrowsing per a Internet Explorer 6,7,8 i FireFox 3,3.6 i 4.

Per crossbrowsing s’entén la creació de pàgines web que es vegin igual amb tots els navegadors.

És, doncs,  l’art d’eliminar les diferències de visualització que hi han entre dieferents navegadors, entre versions d’un mateix navegador o entre un mateix navegador  a diferents sistemes operatius.

Per exemple: les diferències de visualització entre Internet Explorer, FireFox i Chrome; les diferències de visualització entre Internet Explorer 6, 7,8 i 9; o les diferències de visualització entre Windows i Unix.

Un dels aspectes que dificulten el crossbrowsing és el model de caixes del CSS.

El model de caixes aplica a les capes i a un  munt d’etiquetes. El model de caixes especifica els marges, el padding o espai entre els límits  de la caixa i l’espai útil de la caixa, especifica la forma i mida de les vores de la caixa…

 
El model de caixes està definit en una especificació del WWW Consortium i l’honoren tots els navegadors importants, si més no en les seves versions actuals. És l’standard model. Ara bé, les versions antigues de l’Internet Explorer feien servir un model de caixes propi. I les versions modernes han optat per mantenir aquest model per a totes aquelles pàgines HTML que no tinguin DOCTYPE, o que el DOCTYPE defineixi la pàgina com HTML 3, com HTML 4 Transitional, o es tracti d’un document de framesets. El que es coneix com Quirqs mode.

Això ens parla de la importància de donar un DOCTYPE adequat a les pàgines que tinguem que crear.

A Internet n’hi han un munt de pàgines que provoquen que l’Internet Explorer les visualitzi en quirks mode.

Per això, cal tenir present les diferències entre el model de caixes del quirks mode i el model de caixes estàndar.

La següent imatge, agafada de http://www.456bereastreet.com/archive/200612/internet_explorer_and_the_css_box_model/, il·lustra aquestes diferències. Aquesta és una imatge clau que cal tenir present a l’hora de desenvolupar

La tècnica de desenvolupament tenint el cross-browsing en ment seguiria els següents principis:

1. desenvolupar per a un navegador base, per exemple Firefox.
2. separar tots els estils en un document css.
3. examinar el resultat en els navegadors per als que es vol garantir el crossbrowsing, per exemple Internet Explorer
4. fent us de condicionals. En el cas de Internet Explorer es disposa de les etiquetes <!–[IF IE nn ]>   …..    <![END IF] –> (amb nn versió de IE).

 Un bon motiu per a desenvolupar primer amb FireFox és que després és molt senzill associar uns CSS específics per al cross browsing amb IE fent servir les etiquetes condicionals de l’IE. En canvi, si es pren IE com navegador base, aleshores cal utilitzar condicionals amb javascript per a associar CSS a Firefox.

El codi dels condicionals amb FireFox quedaria així

<link rel=”stylesheet” type=”text/css” href=”/css/ff_css.css”/>
<!–[IF IE 7 ]>
<link rel=”stylesheet” type=”text/css” href=”/css/ie7_css.css”/>
<![END IF] –>
<!–[IF IE 8 ]>
<link rel=”stylesheet” type=”text/css” href=”/css/ie8_css.css”/>
<![END IF] –>

com fer taules HTML amb les cantonades rodones? / 14 juny 2010

com fer taules HTML amb les cantonades rodones?

Vet aquí una solució que fa us de la propietat background de les etiquetes TD.

<table cellspacing=”0px” cellpadding=”0px” >
    <tr>
        <td style=”padding:0px;
                   background-image:url(‘AmuntEsquerra.gif’);
                background-position:left top;
                background-repeat:no-repeat;”>               
            <table>
            <tr><td>

                 <!–Aquí va el contingut –>

            </td></tr>
            </table>
        </td>

        <td style=”padding:0px;
                   background-image:url(‘AmuntDreta.gif’);
                   background-position:left top;
                   background-repeat:no-repeat;”
            width=”10px”>
        </td>
    </tr>

    <tr>
        <td style=”padding:0px;
                   background-image:url(‘AvallEsquerra.gif’); 
                   background-position:left top;
                   background-repeat:no-repeat;”
            height=”10px”>
        </td>

        <td style=”padding:0px;
                   background-image:url(‘AvallDreta.gif’); 
                   background-position:left top;
                   background-repeat:no-repeat;”
            height=”10px”
            width=”10px”>
        </td>
    </tr>
</table>

Com han de ser els gifs dels backgrounds?

AvallDreta.gif: el més petit de tots, la cantonada inferior-dreta.

AvallEsquerra.gif: la cantonada inferior esquerra i l’aresta inferior de la caixa.

AmuntDreta.gif: la cantonada superior dreta i l’aresta de la dreta

AmuntEsquerra.gif: ens proporciona el fons de la cel·la útil per mostrar informació. La resta de cel·les només tenen la missió de mostrar les cantonades rodones, és dir, només seran tan amples o altes com ho siguin la corba de la cantonada a mostrar.

Ara tenen sentit els valors de l’HTML, oi? El bo del cas és que el tamany de la caixa d’adaptarà al contingut de la cel·la TD superior esquerra. Cal tenir, doncs, la previsió de dimensionar el tamany dels gifs de backgrounds per a que siguin suficients per a les dades a mostrar.

Com fer que una capa "floti" sobre un flash? / 14 juny 2010

Com fer que una capa “floti” sobre un flash?

Si superposem una capa HTML sobre un flash resultarà que veurem com la capa queda oculta pel flash. La capa está “a sota”. Aleshores, per conseguir l’efecte de que la capa “floti” sobre el flash cal fer el flash “transparent”. Diguem que cal que deixi veure el que “té a sota”. L’efecte que s’aconsegueix és justament que que la capa está flotant “sobre” el flash.
N’hi ha prou amb afegir el paràmetre wmode al tag object (ressaltat en groc), com es mostra en el codi d’exemple.
<object
classid=”clsid:D27CDB6E-AE6D-11cf-96B8-444553540000″
id=”bannerflash”
width=”600″ height=”400″>
<param name=”movie” value=”el-meu-flash.swf” />
<param name=”quality” value=”high” />
<param name=”wmode” value=”transparent” />
src=”el-meu-flash.swf”
quality=”high”
width=”600″ height=”400″
type=”application/x-shockwave-flash”
wmode=”transparent”
</embed>
</object>