<?xml version="1.0" encoding="UTF-8" ?>	<rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"> 
	<channel>
		<title>Blog de Imaginanet S.L. Programacion web y marketing online.</title>
		<link>http://www.imaginanet.com/blog.html</link>
		<description>Blog de Imaginanet. Artículos especializados en soluciones y desarrollo Web 2.0. así como en buscadores web.</description>
		<lastBuildDate>Sat,  4 Feb 2012 03:22:48 +0100</lastBuildDate> 
		<generator>imaginaCMS</generator>
		<language>es</language>
		<sy:updatePeriod>weekly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
		<image> 
		    <title>Blog de Imaginanet S.L. Programacion web y marketing online.</title> 
		    <url>http://www.imaginanet.com/logo.png</url> 
		    <link>http://www.imaginanet.com/blog.html</link> 
		    <width>144</width> 
		    <height>53</height> 
	    </image>
	    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://www.imaginanet.com/feeds.htm" />
	    <feedburner:browserFriendly>
	    	Este es un feed de contenido XML. Para visualizarlo es necesario un programa de lectura de noticias y desde feedburner, el feed está sujeto a los derechos de autor y a un uso responsable. 
	    	/
	    	This is an XML content feed. It is intended to be viewed in a newsreader or syndicated to another site, subject to copyright and fair use.
	    </feedburner:browserFriendly><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" />
			
		<item>
			<title>Patrón MVP</title>
			<link>http://www.imaginanet.com/blog/patron-mvp.html</link>
			<guid>http://www.imaginanet.com/blog/patron-mvp.html</guid>
			<comments>http://www.imaginanet.com/blog/patron-mvp.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Thu,  2 Feb 2012 08:21:30 +0100</pubDate>
					<category><![CDATA[Patrones]]></category>
					<description><![CDATA[El Patr&oacute;n Modelo-Vista-Presentador (MVP) surge para ayudar a realizar pruebas autom&aacute;ticas de la interfaz gr&aacute;fica, para ello la idea es codificar la interfaz de usuario lo m&aacute;s simple posible, teniendo el menor c&oacute;digo posible, de forma que no merezca la pena probarla. En su lugar, toda la...]]></description>
			<content:encoded><![CDATA[><p>El Patr&oacute;n Modelo-Vista-Presentador (MVP) surge para ayudar a realizar pruebas autom&aacute;ticas de la interfaz gr&aacute;fica, para ello la idea es codificar la interfaz de usuario lo m&aacute;s simple posible, teniendo el menor c&oacute;digo posible, de forma que no merezca la pena probarla. En su lugar, toda la l&oacute;gica de la interfaz de usuario, se hace en una clase separada (que se conoce como Presentador), que no dependa en absoluto de los componentes de la interfaz gr&aacute;fica y que, por tanto, es m&aacute;s f&aacute;cil de realizar pruebas.</p>
<p>La idea b&aacute;sica es que la clase Presentador haga de intermediario entre la Vista (la interfaz gr&aacute;fica de usuario) y el modelo de datos. La vista tiene m&eacute;todos en los que le pasan los datos que debe pintar ya "mascados" (una lista de cadenas por ejemplo, en vez del modelo...). &Uacute;nicamente debe meter esos datos en los componentes gr&aacute;ficos (cajas de texto, checkbox, etc). Tambi&eacute;n m&eacute;todos get para obtener el contenido de esos componentes.</p>
<p>El Presentador har&aacute; de enlace entre el modelo y la vista, y dotar&aacute; de inteligencia a la vista. Como el objetivo es poder probarlo f&aacute;cilmente, el Presentador recibe las interfaces que deben implementar el modelo y la vista, con los m&eacute;todos p&uacute;blicos a los que el Presentador debe llamar.</p>
<p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://www.imaginanet.com/ftp/blog/patronmvp.jpg" alt="Patr&oacute;n MVP" width="240" height="185" /></p>
<p>Se puede decir que el patr&oacute;n MVP es una mejora del patr&oacute;n Modelo-Vista-Controlador (MVC) basado en tres caracter&iacute;sticas:</p>
<ul>
<li>La vista no conoce el modelo.</li>
<li>El presentador es independiente de la tecnolog&iacute;a de interfaz de usuario.</li>
<li>La vista y el presentador son testeables puesto que esta basada en un contrato.</li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=95</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/patron-mvp.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Cómo reducir la carga del servidor reduciendo y combinando las hojas de estilo y javascripts</title>
			<link>http://www.imaginanet.com/blog/como-reducir-la-carga-del-servidor-reduciendo-y-combinando-las-hojas-de-estilo-y-javascripts.html</link>
			<guid>http://www.imaginanet.com/blog/como-reducir-la-carga-del-servidor-reduciendo-y-combinando-las-hojas-de-estilo-y-javascripts.html</guid>
			<comments>http://www.imaginanet.com/blog/como-reducir-la-carga-del-servidor-reduciendo-y-combinando-las-hojas-de-estilo-y-javascripts.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Thu, 19 Jan 2012 10:18:02 +0100</pubDate>
					<category><![CDATA[Internet]]></category>
					<category><![CDATA[CSS]]></category>
					<category><![CDATA[Navegadores]]></category>
					<category><![CDATA[PHP]]></category>
					<category><![CDATA[jQuery]]></category>
					<description><![CDATA[El dise&ntilde;o web cada vez se est&aacute; aprovechando de las ventajas de aplicar los conceptos clave de la Ingenier&iacute;a.
Si imaginamos la fabricaci&oacute;n de un coche, podemos verlo como la fabricaci&oacute;n por separado de una serie de piezas (motor, sistema de frenado, ruedas, tapicer&iacute;a, &hellip;) que se...]]></description>
			<content:encoded><![CDATA[><p><em><strong>El dise&ntilde;o web cada vez se est&aacute; aprovechando de las ventajas de aplicar los conceptos clave de la Ingenier&iacute;a</strong></em>.</p>
<p>Si imaginamos la fabricaci&oacute;n de un coche, podemos verlo como la fabricaci&oacute;n por separado de una serie de piezas (motor, sistema de frenado, ruedas, tapicer&iacute;a, &hellip;) que se dise&ntilde;an por separado y se combinan.&nbsp;As&iacute;, en el dise&ntilde;o web muchas veces se combinan librer&iacute;as Javascript como jQuery o m&oacute;dulos personalizados que a&ntilde;aden funcionalidad a la web.</p>
<p>El problema de esto, es que <strong>un navegador est&aacute; obligado a realizar una petici&oacute;n al servidor por cada archivo</strong> (imagen, librer&iacute;a, hoja de estilos, &hellip;) que se utiliza en la p&aacute;gina web. Una vez cargadas, el navegador las cachea y la navegaci&oacute;n resulta m&aacute;s fluida, pero &iquest;C&oacute;mo podemos agilizar ese primer paso tan decisivo?</p>
<p>La respuesta es simple:&nbsp;<strong>Minimizando&nbsp;las peticiones al servidor</strong></p>
<h3><strong>Hojas de estilo y librer&iacute;as Javascript</strong></h3>
<p>Lo ideal es que todas las peticiones vayan en un mismo fichero. Esto en un principio obligar&iacute;a al programador a realizar todo el proceso de la hoja de estilos en un &uacute;nico fichero, lo cual, en algunos casos puede no ser lo m&aacute;s aconsejable por modularidad, aunque s&iacute; por eficiencia.</p>
<p>Existen librer&iacute;as que son capaces de combinar varios ficheros en uno solo de forma autom&aacute;tica cada vez que alguno de los ficheros se modifica. Esto quiz&aacute;s a&ntilde;ada un poco de tiempo de procesamiento en PHP pero las ventajas a la larga cuando la web est&eacute; en producci&oacute;n son grandes.</p>
<h3><br /><strong>Im&aacute;genes</strong></h3>
<p>Si una hoja de estilos hace uso de unas 10 im&aacute;genes de fondo, <strong>tiene que realizar una llamada al servidor por cada una de estas im&aacute;genes</strong>. La soluci&oacute;n para minimizar esto es combinar todas las im&aacute;genes en una sola utilizando una t&eacute;cnica llamada <strong><a href="http://www.librosweb.es/css_avanzado/capitulo1/rollovers_y_sprites.html">CSS Sprites</a></strong>.</p>
<p>Con esta t&eacute;cnica, y mediante hojas de estilo somos capaces de coger como imagen de fondo s&oacute;lo la porci&oacute;n que necesitamos.</p>
<p>No hay que menospreciar el trabajo que lleva generar la imagen combinada adem&aacute;s de calcular las posiciones de cada imagen ya que estamos utilizando uno de los recursos m&aacute;s importantes del programador, que es el tiempo.</p>
<p><br /><br />Para ayudar con esto, existen una serie de herramientas online que permiten simplificar la tarea:</p>
<p>Algunas herramientas son:</p>
<ul>
<li><a href="http://spriteme.org/">http://spriteme.org/</a></li>
<li><a href="http://spritegen.website-performance.org/">http://spritegen.website-performance.org/</a></li>
</ul>
<h3><br /><strong>Minimizar y comprimir los archivos</strong></h3>
<p>Antes hemos comentando las ventajas de combinar los archivos en uno para minimizar el n&uacute;mero de peticiones web. <strong>Si adem&aacute;s, somos capaces de reducir el tama&ntilde;o del fichero en producci&oacute;n estaremos incrementando la eficiencia de nuestra web</strong>.</p>
<p>Para ello, existen dos t&eacute;cnicas que se pueden combinar:</p>
<ul>
<li><strong>Minimizar los ficheros</strong>: Eliminando comentarios, espacios en blanco, &hellip;</li>
<li><strong>Comprimir los ficheros</strong>: Algunos navegadores son capaces de entender que los datos pueden venir comprimidos utilizando alg&uacute;n algoritmo de compresi&oacute;n.&nbsp;</li>
</ul>
<p>Con esto, lo que vamos a conseguir es que el servidor est&eacute; m&aacute;s holgado pues tendr&aacute; que transmitir menos cantidad de datos a cada uno de los clientes que realicen peticiones y por tanto, el rendimiento global ser&aacute; mayor.</p>
<p>Todas estas ventajas las podemos conseguir de forma autom&aacute;tica utilizando la librer&iacute;a <a href="http://code.google.com/p/minify/">minify </a>que se encarga de juntar, combinar y reducir los ficheros indicados.</p>
<p><a href="http://code.google.com/p/minify/">http://code.google.com/p/minify/</a></p>
<h3><br /><strong>Cache</strong></h3>
<p>Es posible que le indiquemos a cada p&aacute;gina web, de manera individual, cuanto tiempo debe pertenecer esta en cache. Las dos posibilidades son:Para p&aacute;ginas est&aacute;ticas es implentar una pol&iacute;tica de establecer una fecha de caducidad de la cache lejanaPara p&aacute;ginas din&aacute;micas usar una fecha aproviada para ayudar al navegador con las peticiones condicionales<br /><br />En servidores como Apache, somos capaces de indicar una fecha relativa a la fecha actual, indicando que la p&aacute;gina caducar&aacute;, por ejemplo, pasados d&iacute;as (e incluso a&ntilde;os) de la fecha de la petici&oacute;n.<br />En el caso de cambinar un componente, es necesario indic&aacute;rselo al navegador a&ntilde;adiendo alg&uacute;n par&aacute;metro a la consulta o a&ntilde;adiendo alg&uacute;n n&uacute;mero de versi&oacute;n al fichero.<br /><strong><br /></strong></p>
<h3><strong>Otros consejos</strong></h3>
<p>Poner las hojas de estilo en la cabecera:&nbsp;Tal y como indica el estandar W3C</p>
<p style="padding-left: 30px;"><em>The HTML specification clearly states that stylesheets are to be included in the HEAD of the page: "Unlike A, [LINK] may only appear in the HEAD section of a document, although it may appear any number of times." Neither of the alternatives, the blank white screen or flash of unstyled content, are worth the risk. The optimal solution is to follow the HTML specification and load your stylesheets in the document HEAD.</em><em><br /></em></p>
<p><em><br /></em>Esto nos indica que poniendo las hojas de estilo all&iacute;, el navegador ser&aacute; capaz de cargar la p&aacute;gina de forma progresiva</p>
<p><br /><strong>Utilizar ficheros externos</strong></p>
<p>Al margen de los beneficios de reusabilidad y modularidad, usando ficheros externos para almacenar nuestras hojas de estilo y scripts permiten al navegador cachearlos.</p>
<p>Por consiguiente, las p&aacute;ginas web son m&aacute;s livianas y tardan menos en descargarse.</p>
<p><br /><strong>Reducir el n&uacute;mero de elementos DOM en la p&aacute;gina</strong></p>
<p>Maquetar de forma clara y sem&aacute;ntica reducen el n&uacute;mero de elementos del &aacute;rbol ya que no es necesario a&ntilde;adir DIVs u otros elementos para corregir problemas de LAYOUT. De esta forma, los scripts ser&aacute;n m&aacute;s r&aacute;pidos y eficientes porque tendr&aacute;n que buscar en menos nodos</p>
<p><br /><strong>Evita tener im&aacute;genes vac&iacute;as</strong></p>
<p>Las im&aacute;genes vac&iacute;as (&lt;img src=&rdquo;&rdquo; alt=&rdquo;Vac&iacute;a&rdquo; /&gt;) o var img = new Image(); img.src=&rsquo;&rsquo;; obligan a los navegadores a realizar peticiones HTTP que no son &uacute;tiles.</p>
<p>&nbsp;</p>
<h3>Fuentes:</h3>
<ul>
<li><a href="http://developer.yahoo.com/performance/rules.html">http://developer.yahoo.com/performance/rules.html</a></li>
<li><a href="http://code.google.com/p/minify/">http://code.google.com/p/minify/</a></li>
<li><a href="http://spritegen.website-performance.org/">http://spritegen.website-performance.org/</a></li>
<li><a href="http://spriteme.org/">http://spriteme.org/</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=94</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/como-reducir-la-carga-del-servidor-reduciendo-y-combinando-las-hojas-de-estilo-y-javascripts.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Instalando un antispam con SpamAssassin y Postfix</title>
			<link>http://www.imaginanet.com/blog/instalando-un-antispam-con-spamassassin-y-postfix.html</link>
			<guid>http://www.imaginanet.com/blog/instalando-un-antispam-con-spamassassin-y-postfix.html</guid>
			<comments>http://www.imaginanet.com/blog/instalando-un-antispam-con-spamassassin-y-postfix.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Tue, 17 Jan 2012 15:46:24 +0100</pubDate>
					<category><![CDATA[Servidores y Seguridad]]></category>
					<category><![CDATA[Linux]]></category>
					<description><![CDATA[Tras leer la documentaci&oacute;n oficial y varias gu&iacute;as de como hacerlo, vamos a explicar nuestra experiencia de c&oacute;mo instalar el antispam SpamAssassin sobre CentOS 6.0 (v&aacute;lido tambi&eacute;n para el resto de distribuciones) utilizando el servicio de correo Postfix, consiguiendo unos muy buenos resultados...]]></description>
			<content:encoded><![CDATA[><div class="content selectable wrapchrome">
<div id="text-block-view-012335f5-60b8-4b9e-8d0e-d8c174810d4e-editable" class="editable wrapchrome">
<p>Tras leer la documentaci&oacute;n oficial y varias gu&iacute;as de como hacerlo, vamos a explicar nuestra experiencia de c&oacute;mo instalar el <strong>antispam SpamAssassin</strong> sobre <strong>CentOS 6.0 </strong>(<span style="text-decoration: underline;">v&aacute;lido tambi&eacute;n para el resto de distribuciones</span>) utilizando el servicio de correo <strong>Postfix</strong>, consiguiendo unos muy buenos resultados para mantenernos libres de spam en nuestros correos.</p>
<p>Esta gu&iacute;a est&aacute; basada en otras (indicadas como referencias) y extendida y m&aacute;s ampliamente explicada en algunos conceptos en los que hemos tenido problemas.</p>
<h3>Instalar Perl</h3>
<p>En primer lugar instalaremos Perl si no lo tenemos instalado:</p>
<pre class="code">yum install perl
yum install perl-Mail-DKIM.noarch
yum install spamassassin
</pre>
<p>En este punto, en nuestro caso nos hemos encontrado con alguna dificultad ya que las librer&iacute;as de SpamAssassin requer&iacute;an Perl 5.8.8 y CentOS 6.0 nos acababa de instalar Perl 6.0, por lo que existir&aacute;n conflictos en paquetes con <span style="text-decoration: underline;">dependencias sin resolver</span>.</p>
<pre class="code">error: Failed dependencies:
perl(:MODULE_COMPAT_5.8.8)
</pre>
Tenemos dos opciones para solucionarlo:<br /> 
<ul>
<li><strong>Actualizar a CentOS 6.2</strong>. Si nuestro servidor no est&aacute; en producci&oacute;n o estamos seguros de lo que hacemos, tal vez sea la mejor opci&oacute;n.</li>
<li><strong>Instalar RPMs de la versi&oacute;n 6.2</strong>. Hemos elegido esta opci&oacute;n ya que el servidor en concreto sobre el que lo hemos hecho ya est&aacute; en producci&oacute;n y nos provocaba bastante incertidumbre el hecho de qu&eacute; pasar&aacute; tras actualizar. Tras buscar en los <a href="http://www.centos.org/modules/tinycontent/index.php?id=30" target="_blank">repositorios oficiales de CentOS</a> hemos elegido uno de ellos como &eacute;ste <a href="ftp://centos.arcticnetwork.ca/pub/centos/6.2/os/x86_64/Packages/" target="_blank">ftp://centos.arcticnetwork.ca/pub/centos/6.2/os/x86_64/Packages/</a>&nbsp; y lo hemos instalado a la vieja usanza, con <em>rpm -Uvh rutadelpaquete.rpm </em>todos los paquetes que est&aacute;n dentro de los paquetes requeridos </li>
</ul>
</div>
<div class="editable wrapchrome">
<h3>Configurando SpamAssassin</h3>
<div class="editable wrapchrome">En primer lugar crearemos el usuario de SpamAssassin</div>
<pre class="code">useradd -d /home/spamfilter -s /bin/false spamfilter
chmod 766 /home/spamfilter
</pre>
<div class="editable wrapchrome">Crear el archivo</div>
<pre class="code">nano /etc/mail/spamassassin/local.cf
</pre>
y pegar
<pre class="code"># Puntuaci&oacute;n para ser marcado spam
required_hits 5.0
# Texto que se antepondr&aacute; al asunto de los emails que sean spam
rewrite_header Subject [*****SPAM*****]
# Encapsular spam en un adjunto al email de aviso
report_safe 1
# Habilitar systema Bayes
use_bayes 1
# Autoaprendizaje
bayes_auto_learn 1
bayes_path /home/spamfilter/
bayes_file_mode 0666
# Comprobaciones de spam
skip_rbl_checks 0
use_razor2 1
use_dcc 1
use_pyzor 1
</pre>
<p>Comprobar si la configuraci&oacute;n es correcta:</p>
<pre class="code">spamassassin --lint
</pre>
<p>Posiblemente nos avise de algunos warnings referentes a las comprobaciones de spam, pero en principio no tiene mayor importancia.</p>
<h3>Configurando Postfix</h3>
Editar /etc/postfix/master.cf. Reemplazaremos la directiva <em>smtp</em> por lo siguiente
<pre class="code">smtp inet n - n - - smtpd
   -o content_filter=spamfilter:dummy
spamfilter unix - n n - - pipe
   flags=Rq user=spamfilter argv=/usr/local/bin/spamfilter.sh -f ${sender} -- ${recipient}
</pre>
<p>Editar /etc/postfix/main.cf</p>
<pre class="code">strict_rfc821_envelopes = yes
disable_vrfy_command = yes
smtpd_helo_required = yes
smtpd_client_restrictions =
smtpd_helo_restrictions =
smtpd_sender_restrictions =
smtpd_recipient_restrictions =
   permit_mynetworks,
   permit_sasl_authenticated,
   reject_unauth_destination,
   reject_invalid_hostname,
   reject_unauth_pipelining,
   reject_non_fqdn_sender,
   reject_unknown_sender_domain,
   reject_non_fqdn_recipient,
   reject_unknown_recipient_domain,
   check_client_access hash:$config_directory/access_client,
   check_sender_access hash:$config_directory/access_sender
   permit
</pre>
<h3 class="editable wrapchrome">Conectando Postfix a SpamAssassin</h3>
<div class="editable wrapchrome">Buscar los binarios <em>spamc</em> y <em>sendmail</em> (variar&aacute; seg&uacute;n la distribuci&oacute;n)
<pre class="code">locate spamc
 /usr/bin/spamc
locate sendmail
 /usr/sbin/sendmail
</pre>
<p>Crear el siguiente script shell</p>
<pre class="code">nano /usr/local/bin/spamfilter.sh
</pre>
<p>y pegar</p>
<pre class="code">#!/bin/bash
/usr/bin/spamc | /usr/sbin/sendmail -i "$@"
exit $?
</pre>
<p>Debemos tener <span style="text-decoration: underline;">mucho cuidado con las rutas</span>, ya que si ponemos mal las rutas los correos no llegar&aacute;n o llegar&aacute;n vac&iacute;os</p>
<pre class="code">chmod 755 /usr/local/bin/spamfilter.sh
chown spamfilter:spamfilter /usr/local/bin/spamfilter.sh
</pre>
<p>Reiniciamos servicios</p>
<pre class="code">/etc/init.d/spamassassin start
/etc/init.d/postfix restart
</pre>
<h3>Actualizar spam assassin y a&ntilde;adirlo al inicio del arranque de Linux</h3>
<p>Actualizaremos el servicio de cron</p>
<pre class="code">crontab -e
</pre>
<p>y a&ntilde;adiremos la siguiente l&iacute;nea para ejecutarse todos los viernes a las 8:01</p>
<pre class="code">01  8  *  *  5  sa-update &amp;&amp; service spamassassin restart
</pre>
<p>Por &uacute;ltimo lo a&ntilde;adimos a los scripts de inicio de CentOS</p>
<pre class="code">chkconfig --add spamd
</pre>
<h3>Borrando el spam recibido</h3>
<p>SpamAssassin no recomienda borrar el correo marcado spam por si ocurren falsos positivos, pero a&uacute;n as&iacute; vamos a filtrar los que claramente sean spam.</p>
<pre class="code">mkdir /var/spamchk
chmod -R 777 /var/spamchk 
chown -R spamfilter:spamfilter /var/spamchk
</pre>
<p>Hacemos una copia de seguridad de /usr/local/bin/spamfilter.sh a simple_spamfilter.sh y editaremos el archivo poniendo</p>
<pre class="code">#!/bin/sh

# Variables
SENDMAIL="/usr/sbin/sendmail -i"
EGREP=/bin/egrep
TMPFILE=/tmp/spamchk.$$
SIDELINE_DIR=/var/spamchk
# Puntuaci&oacute;n m&iacute;nima del correo para ser tratado como spam
SPAMLIMIT=10
# Limpiamos el archivo temporal
trap "rm -f $TMPFILE" 0 1 2 3 15
# Guardamos el mensaje temporalmente en $TMPFILE
cat | /usr/bin/spamc -u filter | sed 's/^.$/../' &gt; $TMPFILE
# Comprobamos si el correo est&aacute; marcado con un alto nivel de spam
if $EGREP -q "^X-Spam-Level: *{$SPAMLIMIT,}" &lt; $TMPFILE
then
  # Opci&oacute;n 1: guardarlos en el disco duro
  # mv $TMPFILE $SIDELINE_DIR/`date +%Y-%m-%d_%R`-$$
  # Opci&oacute;n 2: Env&iacute;alo a una cuenta de correo de spam para tenerlos guardados
   $SENDMAIL spam@xxxx.xx &lt; $TMPFILE
  # Opci&oacute;n 3: Borra el mensaje
  # rm -f $TMPFILE
else
$SENDMAIL "$@" &lt; $TMPFILE
fi
# Postfix devuelve el estado de salida de la llamada a sendmail command.
exit $?
</pre>
<p>El umbral para tratar los correos de spam es la variable SPAMLIMIT. Un valor de 10 es un buen valor inicial, pero deberemos ir cambi&aacute;ndolo hasta afinar con el valor m&aacute;s correcto. Aconsejamos un valor m&iacute;nimo de 5.</p>
<h3>Desinstalando Spam Assassin</h3>
<p>Si tenemos alg&uacute;n problema, podemos desinstalarlo editando /etc/postfix/master.cf reemplazando el contenido</p>
<pre class="code">smtp inet n - n - - smtpd
   -o content_filter=spamfilter:dummy
spamfilter unix - n n - - pipe
   flags=Rq user=spamfilter argv=/usr/local/bin/spamfilter.sh -f ${sender} -- ${recipient}
</pre>
por
<pre class="code">smtp inet n - n - - smtpd
</pre>
<p>despu&eacute;s reinicia los servicios</p>
<pre class="code">/etc/init.d/spamassassin start
/etc/init.d/postfix restart
</pre>
<h3>Instalando una interfaz web para SpamAssassin: webuserprefs</h3>
<p>El hecho de tener que aprender o estar revisando la documentaci&oacute;n para modificar el archivo de configuraci&oacute;n es bastante tedioso. Podemos instalar la interfaz gr&aacute;fica <strong>webuserprefs</strong> (hecha en PHP) que nos ayudar&aacute; en ello.</p>
<p>En nuestro caso crearemos desde Plesk un subdominio para ello. No es necesario, ya que podremos instalarlo en una carpeta, pero por comodidad lo hemos hecho as&iacute;: webuserprefs.xxxxxxx.xxx</p>
<p>Borramos todo el contenido que por defecto trae Plesk y nos situaremos en el directorio objetivo para descargarnos la &uacute;ltima versi&oacute;n de webuserprefs (0.6 en el momento de escribir esta gu&iacute;a).</p>
<p>Lo descomprimiremos y daremos permisos necesarios.</p>
<pre class="code">wget http://downloads.sourceforge.net/project/webuserprefs/webuserprefs/0.6/webuserprefs-0.6.tar.gz
tar xvzf webuserprefs-0.6.tar.gz
chown -R user:group *</pre>
<p>Protegeremos el subdominio mediante "Plesk protected directories system", si no usamos Plesk deberemos usar el sistema de usuarios de Apache y htaccess.</p>
<div class="editable wrapchrome">La aplicaci&oacute;n webuserprefs modifica el archivo $HOME/.spamassassin/user_prefs donde $HOME es el directorio home del usuario que ejecuta spamd (podemos saberlo ejecutando de nuevo <em>spamassassin --lint</em>) pero como webuserprefs es una aplicaci&oacute;n web, las restricciones de PHP open_basedir no nos van a permitir modificarlo. A partir de ahora, $WEBUSERPREFS ser&aacute; el directorio donde est&aacute; webuserprefs.</div>
<div class="editable wrapchrome"></div>
<div class="editable wrapchrome">Una forma f&aacute;cil es crear ese archivo en el directorio donde est&eacute; la ra&iacute;z de webuserprefs y crear un enlace s&iacute;mb&oacute;lico desde $HOME/.spamassassin/user_prefs a &eacute;ste.</div>
<pre class="code">touch $WEBUSERPREFS/user_prefs
chmod 666 $WEBUSERPREFS/user_prefs
cd $HOME/.spamassassin
ln -s $WEBUSERPREFS/user_prefs user_prefs
</pre>
<p>&Eacute;ste archivo estar&aacute; protegido mediante el usuario y contrase&ntilde;a de htaccess y tampoco contiene informaci&oacute;n sensible, como mucho redes o dominios desde no se acepta emails.</p>
<p>Finalmente editaremos webuserprefs desde su archivo de configuraci&oacute;n buscando las siguientes l&iacute;neas y cambi&aacute;ndolas a:</p>
<pre class="code">// require("auth/server.php");
$user_prefs     = "user_prefs";
$group_sort     = "yes";
</pre>
<h3>Fuentes</h3>
<p>Este art&iacute;culo es una mezcla con a&ntilde;adidos y modificaciones en varias partes de &eacute;ste de las siguientes fuentes:</p>
<ul>
<li><a href="http://www.xnote.com/howto/postfix-spamassassin.html" target="_blank">http://www.xnote.com/howto/postfix-spamassassin.html</a></li>
<li><a href="http://www.akadia.com/services/postfix_spamassassin.html" target="_blank">http://www.akadia.com/services/postfix_spamassassin.html</a></li>
<li><a href="http://wiki.apache.org/spamassassin/FrequentlyAskedQuestions" target="_blank">http://wiki.apache.org/spamassassin/FrequentlyAskedQuestions</a></li>
<li><a href="http://wiki.apache.org/spamassassin/DeletingAllMailsMarkedSpam" target="_blank">http://wiki.apache.org/spamassassin/DeletingAllMailsMarkedSpam</a></li>
<li><a href="http://blog.garion.org/2011/04/23/deleting-spam-with-postfix-and-spamassassin/" target="_blank">http://blog.garion.org/2011/04/23/deleting-spam-with-postfix-and-spamassassin/</a></li>
<li><a href="http://wiki.apache.org/spamassassin/WebUserInterfaces" target="_blank">http://wiki.apache.org/spamassassin/WebUserInterfaces</a></li>
<li><a href="http://wiki.apache.org/spamassassin/SingleUserUnixInstall#head-1dd15c06b7e645638def3d2ed2ef31557d853659" target="_blank">http://wiki.apache.org/spamassassin/SingleUserUnixInstall#head-1dd15c06b7e645638def3d2ed2ef31557d853659</a></li>
</ul>
</div>
</div>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=93</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/instalando-un-antispam-con-spamassassin-y-postfix.html</feedburner:origLink>
		</item>
				
		<item>
			<title>HTML 5. Inserción de video o audio en la web</title>
			<link>http://www.imaginanet.com/blog/html-5-insercion-de-video-o-audio-en-la-web.html</link>
			<guid>http://www.imaginanet.com/blog/html-5-insercion-de-video-o-audio-en-la-web.html</guid>
			<comments>http://www.imaginanet.com/blog/html-5-insercion-de-video-o-audio-en-la-web.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Tue, 17 Jan 2012 14:02:32 +0100</pubDate>
					<category><![CDATA[HTML5]]></category>
					<category><![CDATA[Web 2.0]]></category>
					<category><![CDATA[Navegadores]]></category>
					<description><![CDATA[Siempre hay ocasiones en las que es necesario insertar un video o un fichero de audio para que se reproduzca de forma integrada en la web sin neesidad de descargarlo a tu disco duro y abrirlo con tu reproductor habitual.
Hasta ahora esto se ha hecho siempre mediante la inserci&oacute;n de macros a trav&eacute;s de la etiqueta html...]]></description>
			<content:encoded><![CDATA[><p>Siempre hay ocasiones en las que es necesario insertar un <em>video </em>o un fichero de <em>audio </em>para que se reproduzca de forma integrada en la web sin neesidad de descargarlo a tu disco duro y abrirlo con tu reproductor habitual.</p>
<p>Hasta ahora esto se ha hecho siempre mediante la inserci&oacute;n de macros a trav&eacute;s de la etiqueta html <strong><em>iframe </em></strong>o mediante un <em><strong>reproductor flash</strong></em>. Esto tiene dos inconvenientes:</p>
<p>El primero de ellos es que para que todo cuadre en la web. El que lo inserta debe saber el suficiente html para que ajuste el tama&ntilde;o a la proporci&oacute;n adecuada de tal forma que todo se ajuste a la maqueta como deber&iacute;a.</p>
<p>El segundo de los inconvenientes es que la inserci&oacute;n de macros siempre es un problema en cuanto a seguridad, ya que se est&aacute; cargando contenido de otra web en la nuestra, lo cual puede provocar que nuestra web sea portadora de virus si no se utiliza con cuidado.</p>
<p>El flash por su parte, en funci&oacute;n de los navegadores, puede generar graves problemas de rendimiento (Especialmente en Internet Explorer). Adem&aacute;s del hecho de que no es posible reproducir flash en ciertos dispositivos, como los de Apple, en&oacute;rmemente extendidos ha d&iacute;a de hoy.</p>
<p>En el caso de que la web no est&eacute; pensada para ser visualizada en dispositivos m&oacute;viles o tablets, en principio, de esta forma se puede obtener un reproductor de audio o de video muy facilmente. A continuaci&oacute;n vemos unos ejemplos de c&oacute;mo insertar videos flv en la web con un <a href="http://flv-player.net/">reproductor flash</a>,</p>
<p>&lt;object type="application/x-shockwave-flash" data="http://flv-player.net/medias/player_flv.swf" width="300" height="220"&gt;<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;param name="movie" value="http://flv-player.net/medias/player_flv.swf" /&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param name="allowFullScreen" value="true" /&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp; &lt;param name="FlashVars" value="flv=http://www.miweb.es/video.flv" /&gt;<br />&lt;/object&gt;</p>
<p>Con este c&oacute;digo cargaremos un reproductor de video flash que nos permitir&aacute; ver videos flv en nuestra web insert&aacute;ndolo all&iacute; donde queramos que se reproduzca el video. Sin embargo, los sitios como youtube o vimeo, no permiten reproducir los videos de forma directa a traves del reproductor flash, porque ya tienen su propio sistema. En estos casos, debemos, o bien insertar dir&eacute;ctamente le c&oacute;digo iframe que nos ofrece youtube o vimeo para que todo funcione corr&eacute;ctamente ajustando los par&aacute;metros de anchura y altura del iframe que nos dan para que cuadre en donde lo queramos poner. A continuaci&oacute;n se muestra un ejemplo de youtube:</p>
<p>&lt;iframe width="560" height="315" src="http://www.youtube.com/embed/bxP0VnbHSxE" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;</p>
<p>Existe una alternativa que, aunque tambien pasa por los iframes, facilita mucho la labor para alguien que no sabe HTML. Tanto Youtube como Vimeo, tienen un c&oacute;digo asociado a cada uno de sus videos que acompa&ntilde;a a la url mediante par&aacute;metros get. De cara al porgramador es algo m&aacute;s laborioso, porque debe procesar el enlace por php, extraer el c&oacute;digo citado de youtube o vimeo, y acoplarlo a un enlace de tipo embed de la web que corresponda (Youtube o Vimeo). B&aacute;sicamente, se trata de montar nuestro propio iframe sabiendo cual es el formato de los enlacess embed de Vimeo y de Youtube, los cuales podemos ver facilmente en los iframes para insertar un video que nos proporcionan dichas webs.</p>
<p>En el caso del audio, tambien se usa un c&oacute;digo flash que carga el reproductor instalado por defecto en nuestro navegador. El m&aacute;s utilizado suele ser Windows media player, debido a al gran expansi&oacute;n de los sistemas operativos Windows.</p>
<p>&nbsp;</p>
<h3>Etiquetas audio y video de HTML 5</h3>
<p>En HTML 5 tenemos la posibilidad de reproducir audio y video dir&eacute;ctamente mediante el uso de las etiquetas <strong>audio</strong> y <strong>video</strong>.</p>
<h3>La etiqueta Audio</h3>
<p>Nos permite insertar un fichero de audio con un reproductor en nuestra web, que nos permitira escucharlo sin necesidad de tener instalado ning&uacute;n programa adicional para dicho fin. Un ejemplo de sintaxis de esta etiqueta ser&iacute;a el siguiente:</p>
<p>&lt;audio src=&rdquo;audio.mp3&Prime; type=&rdquo;audio/mp3&Prime; controls autoplay /&gt;</p>
<p>A continuaci&oacute;n se expone una breve descripci&oacute;n de algunos de los atributos disponibles para esta etiqueta.</p>
<p><em><strong>src</strong></em>. Indica la ruta del archivo a reproducir.</p>
<p><em><strong>autoplay</strong></em>. Permite que la reproducci&oacute;n comience de forma autom&aacute;tica sin previo aviso. En ocasiones no se recomienda su uso para dejar que el usuario decida cuando reproducir audio cuando lo desee.</p>
<p><em><strong>autobuffer</strong></em>. Nos permite cargar de forma autom&aacute;tica el archivo para que sea m&aacute;s r&aacute;pida su reproducci&oacute;n a posteriori y reducir a&iacute; tiempos de espera para el usuario.</p>
<p><em><strong>width </strong></em>y height. Definen respectivamente la anchura y la altura que debera&aacute; tener la etiqueta de audio.</p>
<p><em><strong>loop</strong></em>. Ejecuta la reproducci&oacute;n en bucle de forma que al finalizar vuelve a empezar.</p>
<p><em><strong>controls</strong></em>. Muestra los controles de reproducci&oacute;n.</p>
<p><em><strong>type</strong></em>. Define el tipo de archivo a reproducir y su extensi&oacute;n (video, audio...)/(mp3, ogg...).</p>
<h3>La etiqueta Video</h3>
<p>En el caso de la etiqueta de video, atributos son muy similares a los de la etiqueta audio. Aqu&uacute; un ejemplo de su sint&aacute;xis.</p>
<p>&lt;video src=&rdquo;video.ogg&rdquo;&gt;<br /> &lt;!&ndash; C&oacute;digo a mostrar en navegadores que no soportan HTML 5 &ndash;&gt;<br /> &lt;/video&gt;</p>
<p>Para m&aacute;s informaci&oacute;n pod&eacute;is consultar <a href="http://dev.w3.org/html5/spec/Overview.html#the-audio-element">este enlace</a>.<em>&nbsp;</em></p>
<p><em>El inconveniente de utilizar estas etiquetas es que hay navegadores que no soportan corr&eacute;ctamente todas las funcionalidades de html5 y por ese motivo no se utilizan todav&iacute;a de forma habitual.<br /></em></p>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=92</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/html-5-insercion-de-video-o-audio-en-la-web.html</feedburner:origLink>
		</item>
				
		<item>
			<title>El Proyecto FFMPEG</title>
			<link>http://www.imaginanet.com/blog/el-proyecto-ffmpeg.html</link>
			<guid>http://www.imaginanet.com/blog/el-proyecto-ffmpeg.html</guid>
			<comments>http://www.imaginanet.com/blog/el-proyecto-ffmpeg.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Fri, 30 Dec 2011 17:02:12 +0100</pubDate>
					<category><![CDATA[Android]]></category>
					<category><![CDATA[Linux]]></category>
					<description><![CDATA[FFMPEG es un r&aacute;pido sistema de conversi&oacute;n de v&iacute;deo y audio, que adem&aacute;s de permitir la conversi&oacute;n entre muchos de los formatos conocidos como MP4, MPEG para video y mp3 o amr para audio, entre otros.
FFServer nos permite transmitir video y audio que haya sido previamente convertido a alguno de los...]]></description>
			<content:encoded><![CDATA[><p>FFMPEG es un r&aacute;pido sistema de conversi&oacute;n de v&iacute;deo y audio, que adem&aacute;s de permitir la conversi&oacute;n entre muchos de los formatos conocidos como MP4, MPEG para video y mp3 o amr para audio, entre otros.</p>
<p>FFServer nos permite transmitir video y audio que haya sido previamente convertido a alguno de los formatos soportados por FFMPEG adem&aacute;s de hacerlo tambi&eacute;n en tiempo real combin&aacute;ndolo con FFMPEG, mediante flujos FFM.</p>
<p>FFPlay es un reproductor de medios muy sencillo que utiliza las librer&iacute;as de FFMPEG y SDL. Normalmente, se utiliza como sistema de testeo cuando se trabaja con FFMPEG.</p>
<p>Ahora que ya conocemos las distintas herramientas que vamos a utilizar, podemos empezar a analizarlas con un poco m&aacute;s de profundidad.</p>
<p>&nbsp;</p>
<p><strong>FFMPEG</strong></p>
<p><strong><em><span style="text-decoration: underline;">Funcionamiento</span></em></strong></p>
<p>FFMPEG, funciona por l&iacute;nea de comandos. La forma general de invocar a FFMPEG es la siguiente:</p>
<p>ffmpeg [[Opciones para el fichero de entrada][-i Fichero de entrada]]&hellip;{[Opciones para el fichero de salida] Fichero de salida}.</p>
<p>Mediante esta estructura general tan sencilla, FFMPEG no s&oacute;lo nos permite convertir ficheros que se encuentren en nuestro PC, sino que podemos capturar el v&iacute;deo o el audio, en funci&oacute;n de lo que nos interese, desde cualquier fuente, ya sea una tarjeta capturadora de video o una direcci&oacute;n IP de una m&aacute;quina local o remota en la que se encuentre el fichero de audio o video a convertir.</p>
<p>&nbsp;</p>
<p>A continuaci&oacute;n veremos las opciones de FFMPEG m&aacute;s importantes y que se suelen usar con m&aacute;s frecuencia.</p>
<p><strong><em><span style="text-decoration: underline;">Opciones Principales</span></em></strong></p>
<p><strong>-h</strong></p>
<p>Nos muestra la ayuda del programa, es decir, nos muestra cuales son las diferentes opciones que FFMPEG acepta como argumento.</p>
<p><strong>-formats</strong></p>
<p>Nos muestra una lista de los formatos que soporta el programa tanto de entrada como de salida. Los campos que preceden al nombre del formato nos dicen si ese formato es aceptado como par&aacute;metro de entrada o como par&aacute;metro de salida.</p>
<p><em><span style="text-decoration: underline;">&lsquo;D&rsquo;</span></em> (<em>Decoding Available</em>). Si el nombre de un formato viene precedido de este campo, nos dice que es posible decodificar dicho formato, es decir, que FFMPEG lo puede recibir como par&aacute;metro de entrada.</p>
<p><em><span style="text-decoration: underline;">&lsquo;E&rsquo;</span></em> (<em>Encoding available</em>). Este campo por su parte, no informa sobre la posibilidad de codificar este formato, lo que nos indica que se puede utilizar como par&aacute;metro de salida de FFMPEG.</p>
<p><strong>-codecs</strong></p>
<p>Esta opci&oacute;n nos permite saber cuales de los codecs (codificadores, decodificadores o ambos) est&aacute;n disponibles en el programa. Los campos que preceden al nombre de del c&oacute;dec, nos dicen si el codificador o el decodificador est&aacute;n disponibles y si lo est&aacute;n para audio o v&iacute;deo.</p>
<p><em><span style="text-decoration: underline;">&lsquo;D&rsquo;</span></em>&nbsp; (<em>Decoding Available</em>). Nos indica si el decodificador est&aacute; disponible para ese c&oacute;dec.</p>
<p><em><span style="text-decoration: underline;">&lsquo;E&rsquo;</span></em> (<em>Encoding Available</em>). Si este campo est&aacute; presente, nos dice que el codificador est&aacute; disponible para el c&oacute;dec a cuyo nombre precede.</p>
<p><em><span style="text-decoration: underline;">V/A/S</span></em>. Nos indica si el c&oacute;dec est&aacute; disponible para audio, v&iacute;deo o subt&iacute;tulos.</p>
<p><em><span style="text-decoration: underline;">&lsquo;S&rsquo;</span></em>. Es lo que nos indica si el c&oacute;dec soporta cortes.</p>
<p><em><span style="text-decoration: underline;">&lsquo;D&rsquo;</span></em>. El c&oacute;dec soporta renderizado directo.</p>
<p><em><span style="text-decoration: underline;">&lsquo;T&rsquo;</span></em>. El c&oacute;dec es capaz de manejar videos a la entrada que est&eacute;n truncados aleatoriamente en lugar de en los l&iacute;mites de en los frames &uacute;nicamente.</p>
<p><strong>-f formato</strong></p>
<p>La opci&oacute;n &lsquo;-f &rsquo;, nos permite especificar el formato que tiene nuestro video de entrada y el que tendr&aacute; el video a la salida.</p>
<p><strong>-i</strong></p>
<p>Esta opci&oacute;n es la que nos permite especificar la fuente de la que se extraer&aacute; el video, ya sea local o remota.</p>
<p>Si la fuente es local, tendremos sentencias como esta: ffmpeg &ndash;i video.yuv.</p>
<p>Si por el contrario, la fuente es remota podremos encontrarnos con sentencias como esta: ffmpeg &ndash;i tcp://192.168.3.25:5432.</p>
<p>&nbsp;</p>
<p><strong>-target type</strong></p>
<p>Transforma el fichero de la entrada al formato que se indica en el campo &lsquo;type&rsquo;, ajustando autom&aacute;ticamente opciones como el bitrate, el c&oacute;dec, o el tama&ntilde;o del buffer.</p>
<p><strong><em><span style="text-decoration: underline;">Opciones de Video</span></em></strong></p>
<p><strong>-b &lsquo;bitrate&rsquo;</strong></p>
<p>Nos permite modificar el ratio de bits (en Kbps) que se usar&aacute; para nuestro video tanto a la entrada como a la salida.</p>
<p><strong>-r &lsquo;fps&rsquo;</strong></p>
<p>Nos permite modificar el n&uacute;mero de im&aacute;genes por segundo que se mostrar&aacute;n en nuestro video.</p>
<p><strong>-s &lsquo;size&rsquo;</strong></p>
<p>Con esta opci&oacute;n podemos establecer la resoluci&oacute;n, ya sea manualmente introduciendo los valores&nbsp; de la forma &lsquo;WxH&rsquo;, donde &lsquo;W&rsquo; es el ancho y &rsquo;H&rsquo; la altura, o bien usando alguna de las abreviaturas&nbsp; que reconoce el programa para establecer aluna resoluci&oacute;n est&aacute;ndar como por ejemplo HD a 1080p que se puede especificar como &lsquo; ffmpg &ndash;i video.avi &ndash;s hd1080 videohd.mpeg&rsquo;.</p>
<p><strong>-aspect &lsquo;aspect&rsquo;</strong></p>
<p>Incluyendo esta opci&oacute;n, podremos especificar el formato de pantalla en el que se va a visualizar el video, y por tanto lo adaptaremos a dicho formato de pantalla. Los m&aacute;s conocidos son el formato &lsquo;4 : 3&rsquo; y el formato &lsquo;16 : 9&rsquo; (pantalla panor&aacute;mica).</p>
<p><strong>-vcodec &lsquo;codec&rsquo;</strong></p>
<p>Nos permite establecer un c&oacute;dec determinado para realizar la conversi&oacute;n de video.</p>
<p><strong><em><span style="text-decoration: underline;">Opciones de Audio</span></em></strong></p>
<p><strong>-ar&nbsp; &lsquo;freq&rsquo;</strong></p>
<p>Con esta opci&oacute;n podemos seleccionar la frecuencia de muestreo para nuestro fichero de audio.</p>
<p><strong>-ab &lsquo;bitrate&rsquo;</strong></p>
<p>Esto nos permite seleccionar el n&uacute;mero de bits por segundo en el fichero de audio en Kilobits por segundo, donde sus valores m&aacute;s frecuentes son 64 Kbps, 128 Kbps o 192 Kbps.</p>
<p><strong>-ac &lsquo;chanels&rsquo;</strong></p>
<p>Nos permite decidir a qu&eacute; tipo de sonido se adaptar&aacute; nuestro fichero de audio, mono (opci&oacute;n &lsquo;1&rsquo;) o est&eacute;reo (opci&oacute;n &lsquo;2&rsquo;).</p>
<p>Adem&aacute;s de las citadas en este documento, FFMPEG, ofrece una amplia gama de opciones que nos permiten realizar m&uacute;ltiples cambios en los ficheros a la entrada y a la salida, ya sean de audio o de video, e independiente mente, de si su fuente es un fichero propiamente dicho o una tarjeta capturadora de televisi&oacute;n o una dispositivo externo de video digital como por ejemplo una c&aacute;mara que grabe en formato dv1. Para tener una visi&oacute;n m&aacute;s completa sobre el funcionamiento de FFMPEG, conviene revisar la documentaci&oacute;n oficial del proyecto que se puede encontrar en <a href="http://www.ffmpeg.org/">www.ffmpeg.org</a> o bien, si ya tenemos instalado FFMPEG en el equipo, usar el comando &lsquo;man&rsquo; para acceder a la ayuda del mismo.</p>
<p><strong><em><span style="text-decoration: underline;">Algunos Ejemplos de Aplicaci&oacute;n</span></em></strong></p>
<p>Ahora que ya hemos visto algunas de las opciones m&aacute;s importantes de FFMPEG de cara al proyecto, para una mejor comprensi&oacute;n nos valdremos de algunos ejemplos que servir&aacute;n para tener una idea gr&aacute;fica de lo que hacen las opciones y de c&oacute;mo se pueden combinar.</p>
<p>Por ejemplo podemos convertir un fichero&nbsp; YUV420P a un&nbsp; .avi con la siguiente sentencia:</p>
<p><em>ffmpeg -i /home/prueba.yuv /home/salida.avi</em>.</p>
<p>Tambi&eacute;n podemos realizar el proceso contrario, obteniendo como resultado un fichero de video puro (YUV420P).</p>
<p><em>ffmpeg &ndash;i /home/video.avi videoPuro.yuv.</em></p>
<p>Tambi&eacute;n podemos establecer m&aacute;s de un fichero a la entrada cuando queremos que estos se conviertan a un mismo formato de esta forma.</p>
<p><em>ffmpeg &ndash;i /tmp/a.wav &ndash;s 640x480 &ndash;i /tmp/a.yuv /tmp/a.mpg.</em></p>
<p>De esta forma convertiremos los dos ficheros tanto el de video como el de audio a mpeg. Tendremos dos ficheros nombrados exactamente igual, pero en el uno habr&aacute; audio y en el otro video.</p>
<p>Si se necesitan m&aacute;s ejemplos se puede acudir a <a href="http://www.ffmpeg.org/">www.ffmpeg.org</a> y consultar la secci&oacute;n de documentaci&oacute;n para tener todos los ejemplos de conversi&oacute;n entre formatos, ya sean de audio o de video.</p>
<p>&nbsp;</p>
<p><strong>FFSERVER</strong></p>
<p>FFServer es un sistema que nos permite transmitir ficheros de audio o video en tiempo real o con ficheros previamente convertidos. Este programa funciona mediante un fichero de configuraci&oacute;n denominado ffserver.conf, situado en /etc.</p>
<p>Se puede ejecutar de forma individual utilizando la siguiente sintaxis:</p>
<p>ffserver [Opciones].</p>
<p>Tambi&eacute;n podemos arrancarlo cuando ejecutamos FFMPEG solicit&aacute;ndole una fuente o un destino remoto.</p>
<p>A continuaci&oacute;n veremos las principales opciones que FFServer nos proporciona para su ejecuci&oacute;n por l&iacute;nea de comandos.</p>
<p><strong><em><span style="text-decoration: underline;">Opciones</span></em></strong></p>
<p><strong>-L</strong></p>
<p>Nos muestra la licencia del programa.</p>
<p><strong>-version</strong></p>
<p>Nos indica la versi&oacute;n que tenemos instalada en nuestro equipo.</p>
<p><strong>-formats</strong></p>
<p>Nos muestra una lista de los formatos, codecs y protocolos que soporta FFServer, entre otros.</p>
<p><strong>-f </strong>&lsquo;Fichero de Configuraci&oacute;n.</p>
<p>Nos permite especificar un fichero de configuraci&oacute;n alternativo al existente en /etc/ffserver.conf.</p>
<p><strong>-n</strong></p>
<p>Esta opci&oacute;n anula todas las directivas de ejecuci&oacute;n que permiten al programa ejecutar FFMPEG de forma autom&aacute;tica. De este modo, el usuario tendr&aacute; que ejecutar FFMPEG de forma manual.</p>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=91</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/el-proyecto-ffmpeg.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Cómo visualizar videos FLV en fancybox</title>
			<link>http://www.imaginanet.com/blog/como-visualizar-videos-flv-en-fancybox.html</link>
			<guid>http://www.imaginanet.com/blog/como-visualizar-videos-flv-en-fancybox.html</guid>
			<comments>http://www.imaginanet.com/blog/como-visualizar-videos-flv-en-fancybox.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Fri, 23 Dec 2011 14:37:57 +0100</pubDate>
					<category><![CDATA[Flash]]></category>
					<category><![CDATA[JavaScript]]></category>
					<description><![CDATA[Es muy com&uacute;n a d&iacute;a de hoy colocar videos en nuestras p&aacute;ginas web. Para ello tenemos dos alternativas utilizar alg&uacute;n proveedor de videos que nos preste su ancho de banda (youtube, vimeo, &hellip;) o utilizar el de nuestro servidor. Hay casos en los que elegir nuestro servidor puede ser debido a motivos...]]></description>
			<content:encoded><![CDATA[><p>Es muy com&uacute;n a d&iacute;a de hoy colocar videos en nuestras p&aacute;ginas web. Para ello tenemos dos alternativas utilizar alg&uacute;n proveedor de videos que nos preste su ancho de banda (youtube, vimeo, &hellip;) o utilizar el de nuestro servidor. Hay casos en los que elegir nuestro servidor puede ser debido a motivos de privacidad de los contenidos.</p>
<p>Sea como sea, si lo que te interesa es subir un video FLV a tu propio servidor y adem&aacute;s utilizarlo con el plugin Fancybox, entonces puedes seguir leyendo. Lo primero es tener un reproductor de FLV para web. Hay cientos de reproductores disponibles, tanto gratuitos como de pago, tan solo hay que buscar flv player en google. Podeis utilizar por ejemplo el de flv-player.net que tiene varias versiones (completas o m&aacute;s ligeras sin algunas funcionalidades).</p>
<p>Una vez tenemos el archivo flv y el reproductor flv (es un archivo swf), ya solo nos falta descargar Fancybox. Suponemos que sabemos utilizar fancybox, por tanto montamos una p&aacute;gina sencilla que requiera los archivos javascript necesarios as&iacute; como sus hojas de estilos.</p>
<p>En est&aacute; pagina a&ntilde;adimos un enlace:</p>
<pre class="code"><a class="&rdquo;video_flv&rdquo;" href="/imaginanet/&rdquo;#flv&rdquo;">Ver video</a>
</pre>
<p>Si nos fijamos en el href le hemos colocado un id. De esta forma fancybox cargar&aacute; el contenido de dicho identificador en el popup que abra. Por tanto ahora solo nos falta definir dicho identificador.</p>
<pre class="code"><div style="display: none;">
	<div id="flv">
              <object width="680" height="495" data="/player_flv_maxi.swf" type="application/x-shockwave-flash"><param name="data" value="/player_flv_maxi.swf" /><param name="FlashVars" value="flv=mi_video.flv&amp;showstop=1&amp;showvolume=1&amp;showtime=1&amp;showfullscreen=1" /><param name="src" value="/player_flv_maxi.swf" /></object>								
        </div>
</div>	
</pre>
<p>Hemos introducido la capa con identificador &ldquo;flv&rdquo; dentro de otra capa con &ldquo;display&rdquo; &ldquo;none&rdquo;, de esta manera al entrar en la p&aacute;gina no aparecer&aacute; el video directamente. Dentro de la capa &ldquo;flv&rdquo; tenemos la etiqueta &ldquo;object&rdquo; que lleva el reproductor de FLV (player_flv_maxi.swf) y una serie de parametros para configurar el reproductor donde el m&aacute;s importante es el que define el video a reproducir y cuyo nombre es &ldquo;flv&rdquo;. En el ejemplo vemos como le asignamos mi_video.flv como video a reproducir.</p>
<p>Finalmente solo nos falta el c&oacute;digo javascript que va a hacer que al hacer click en nuestro enlace se abra Fancybox con nuestro video.</p>
<pre class="code">$("a.video_flv").fancybox({
'overlayOpacity': 0,
	'hideOnContentClick': false,
	'padding': 0,
	'autoScale': false,
	'autoDimensions': false,
	'width': 680,
	'height': 495,								
	'titleShow': false,
	'overlayColor': '#000'
});
</pre>
<p>Estamos utilizando un selector con jquery para a&ntilde;adirle el evento de fancybox con una configuraci&oacute;n donde cabe destacar el autoscale y autodimensions desactivados para asi fijar el tama&ntilde;o del popup a abrir. De esta forma conseguimos ver nuestro video flv en fancybox.</p>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=90</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/como-visualizar-videos-flv-en-fancybox.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Maquetación en HTML5</title>
			<link>http://www.imaginanet.com/blog/maquetacion-en-html5.html</link>
			<guid>http://www.imaginanet.com/blog/maquetacion-en-html5.html</guid>
			<comments>http://www.imaginanet.com/blog/maquetacion-en-html5.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Tue, 13 Dec 2011 16:35:26 +0100</pubDate>
					<category><![CDATA[Web 2.0]]></category>
					<category><![CDATA[CSS]]></category>
					<category><![CDATA[HTML5]]></category>
					<description><![CDATA[HTML5 nos brinda la posibilidad de poder a&ntilde;adir m&aacute;s sem&aacute;ntica a nuestras webs,  	pudiendo hacer distinciones entre bloques de contenido utilizando etiquetas  	como &lt;ARTICLE&gt;, &lt;SECTION&gt;, &lt;HEADER&gt;, &lt;FOOTER&gt;, &hellip; en lugar de poder distinguir &uacute;nicamente  	por estructura entre...]]></description>
			<content:encoded><![CDATA[><p><strong>HTML5</strong> nos brinda la posibilidad de poder a&ntilde;adir m&aacute;s sem&aacute;ntica a nuestras webs,  	pudiendo hacer distinciones entre bloques de contenido utilizando etiquetas  	como <strong>&lt;ARTICLE&gt;</strong>, <strong>&lt;SECTION&gt;</strong>, <strong>&lt;HEADER&gt;</strong>, <strong>&lt;FOOTER&gt;</strong>, &hellip; en lugar de poder distinguir &uacute;nicamente  	por estructura entre elementos de bloque o elementos en l&iacute;nea.</p>
<p>Como siempre, el principal problema al que nos enfretamos es la retrocompatibilidad con los navegadores ya que  	las versiones m&aacute;s antiguas de estos no entienden estas estructuras y no las  	representan de forma correcta.</p>
<p>Lo bueno es que, gracias a un poco de <strong>CSS</strong> y <strong>Javascript</strong> podemos "<em>ayudar</em>" a dichos navegadores a  	"<em>entender</em>" dichas etiquetas.</p>
<h3>Estructura de p&aacute;gina en HTML5. Olvid&aacute;ndonos del DOCTYPE</h3>
<p>La declaraci&oacute;n de una p&aacute;gina en HTML5 es mucho m&aacute;s sencilla que en las versiones anteriores:</p>
<pre class="code">&lt;!DOCTYPE html&gt;
&lt;html lang="es"&gt;
	&lt;head&gt;
		&lt;!-- Title --&gt;
		&lt;title&gt;{title}&lt;/title&gt;


		&lt;!-- Meta data --&gt;
		&lt;meta charset="UTF-8"&gt;
		&lt;meta name="description" content="{meta_descripcion}" /&gt; 
		&lt;meta name="keywords" content="{meta_keywords}" /&gt; 
		&lt;meta name="robots" content="index,all" /&gt;

		&lt;!--[if lte IE 8]&gt;
		&lt;script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"&gt;&lt;/script&gt;
		&lt;![endif]--&gt;		

		&lt;!-- Stylesheets --&gt;
		&lt;link rel="stylesheet" href="style/style.css"&gt;

		&lt;!-- Javascripts --&gt;
		&lt;script type="text/javascript" src="js/jquery.js"&gt;&lt;/script&gt;
	&lt;/head&gt;

	&lt;body&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
De todo esto, nos tiene que haber llamado la atenci&oacute;n una cosa:
<pre class="code">	&lt;!--[if lte IE 8]&gt;
	&lt;script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"&gt;&lt;/script&gt;
	&lt;![endif]--&gt;	
</pre>
<p>Esta l&iacute;nea indica que si nuestra versi&oacute;n de navegador es m&aacute;s peque&ntilde;o o igual que Internet Explorer 8, entonces hay que cargar el fichero html5.js que informar&aacute; al navegador de los nuevos elementos.</p>
<h3>Maquetaci&oacute;n de los nuevos elementos</h3>
<p>Al inicio de nuestra hoja de estilos, normalmente aplicamos una serie de estilos que sirven para "<em>resetear</em>"  	las hojas de estilos propias del navegador y as&iacute; intentar dar uniformidad a como se visualiza la p&aacute;gina en distintos  	navegadores y sistemas operativos.</p>
<p>Este ser&iacute;a un ejemplo de dichas reglas:</p>
<pre class="code">/* Reset the stylesheet */
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, font, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
dl, dt, dd, ol, ul, li,
fieldset, textarea, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
address, article, aside, audio, canvas, command, datalist, 
details, dialog, figure, figcaption, footer, header, hgroup,
keygen, mark, meter, menu, nav, progress,
ruby, section, time, video {
  margin: 0;
  padding: 0;
  border: 0;
  outline: 0;
  font-weight: inherit;
  font-style: inherit;
  font-size: 100%;
  font-family: inherit;
  vertical-align: baseline;
}
</pre>
<p>Como vemos, hemos incluido adem&aacute;s de las etiquetas t&iacute;picas de XHTML1.1 y HTML 4.1, las nuevas etiquetas de 	<em>address, article, aside, audio, canvas, command, datalist, details, dialog, figure, figcaption,  	footer, header, hgroup, keygen, mark, meter, menu, nav, progress, ruby, section, time, video.</em></p>
<p>Adem&aacute;s, con esta regla, vamos a especifcar cu&aacute;les de dichos elementos queremos que sean tratados como elementos de bloque.</p>
<pre class="code">/* HTML5 elements that are blocks */
aside, header, footer, article, section, 
nav, figure, figcaption {
	display: block;
}
</pre>
<p>Gracias a estos sencillos pasos podemos empezar a maquetar nuestras webs utilizando las ventajas de HTML5 ya que permitir&aacute;n que los resultados de motores de b&uacute;squeda sean m&aacute;s precisos con nuestros resultados adem&aacute;s de permitir, de forma sencilla, la sindicaci&oacute;n de contenidos o la publicaci&oacute;n de art&iacute;culos en las redes sociales.</p>
<p>Para m&aacute;s informaci&oacute;n sobre HTML5 puede leer la entrada <a href="http://www.imaginanet.com/blog/como-usar-html-5.html">C&oacute;mo usar HTML5</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=89</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/maquetacion-en-html5.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Programando un pasador o slider con jQuery y CSS</title>
			<link>http://www.imaginanet.com/blog/programando-un-pasador-o-slider-con-jquery-y-css.html</link>
			<guid>http://www.imaginanet.com/blog/programando-un-pasador-o-slider-con-jquery-y-css.html</guid>
			<comments>http://www.imaginanet.com/blog/programando-un-pasador-o-slider-con-jquery-y-css.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Tue, 13 Dec 2011 13:46:53 +0100</pubDate>
					<category><![CDATA[jQuery]]></category>
					<category><![CDATA[CSS]]></category>
					<description><![CDATA[La construcci&oacute;n de Sliders es una tarea que se ha simplificado mucho desde el surgimiento de  	frameworks y librer&iacute;as javascript como jQuery o Prototype. Lo que antes era una tarea ardua  	y pesada ahora es tarea de unas pocas l&iacute;neas de c&oacute;digo.
Para un ingeniero de Software, la tarea es ahora de...]]></description>
			<content:encoded><![CDATA[><p>La construcci&oacute;n de <strong>Sliders</strong> es una tarea que se ha simplificado mucho desde el surgimiento de  	frameworks y librer&iacute;as javascript como <strong>jQuery</strong> o <strong>Prototype</strong>. Lo que antes era una tarea ardua  	y pesada ahora es tarea de unas pocas l&iacute;neas de c&oacute;digo.</p>
<p>Para un ingeniero de Software, la tarea es ahora de encontrar una forma est&aacute;ndar de desarrollar dichos pasadores de forma  	que su soluci&oacute;n se aplique a la mayor&iacute;a (<em>sino a todos</em>) de los casos posibles de forma que no tenga pr&aacute;cticamente  	que modificar el c&oacute;digo generado ante cambios de dise&ntilde;o, como n&uacute;mero de elementos, paginadores, &hellip;</p>
<p>En el presente art&iacute;culo vamos a estudiar los elementos que contiene un slider, unos principios b&aacute;sicos de  	funcionamiento y una serie de pr&aacute;cticas &uacute;tiles en su programaci&oacute;n.</p>
<h3>Elementos del pasador</h3>
<p>Podemos distinguir entre los siguientes elementos dentro de un Slider:</p>
<ul>
<li><strong>Contenedor principal</strong>: Sirve para agrupar todos los elementos del Slider.</li>
<li><strong>Men&uacute; de navegaci&oacute;n</strong>. Contiene el men&uacute; que nos va a permitir navegar por los elementos. Pueden ser botones de anterior y siguiente o un paginador, por ejemplo.</li>
<li><strong>Capa contenedora</strong>. Este elemento sirve para determinar cual es el &aacute;rea visible que se a ver en pantalla. El truco consiste en ponerle unas dimensiones fijas y la propiedad overflow a hidden, para ocultar todo el contenido que se salga de su interior. Adem&aacute;s, tiene que tener posicionamiento relativo para poder especificar el posicionamiento absoluta del listado de elementos.</li>
<li><strong>Listado de elementos: </strong>Este elemento est&aacute; dentro de la capa contenedora y tiene un tama&ntilde;o que excede a su padre. Adem&aacute;s, tiene posicionamiento absoluto para poder animar la posici&oacute;n del listado respecto a la capa contenedora.</li>
</ul>
<p>Un ejemplo de este funcionamiento ser&iacute;a esto:</p>
<p><img src="http://www.imaginanet.com/ftp/blog/articulo-slider/funcionamiento-slider.png" alt="Ejemplo de funcionamiento" /></p>
<h3>Maquetaci&oacute;n del slider</h3>
<p>La maquetaci&oacute;n de los elementos anteriormente descritos podr&iacute;a ser as&iacute;:</p>
<pre class="code">	&lt;!-- Slider --&gt;
	&lt;div class=&rdquo;slider&rdquo;&gt;

		 &lt;!-- Capa contenedora --&gt;
		 &lt;div class=&rdquo;contenedor&rdquo;&gt;

	&lt;!-- Listado de elementos --&gt;
				&lt;ul&gt;
					 &lt;li&gt;&lt;img src=&rdquo;images/img1.jpg&rdquo; alt=&rdquo;image 1&rdquo;&gt;&lt;/li&gt;
					 &lt;li&gt;&lt;img src=&rdquo;images/img2.jpg&rdquo; alt=&rdquo;image 2&rdquo;&gt;&lt;/li&gt;
					 &lt;li&gt;&lt;img src=&rdquo;images/img3.jpg&rdquo; alt=&rdquo;image 3&rdquo;&gt;&lt;/li&gt;
				&lt;/ul&gt;
		 &lt;/div&gt;

		 &lt;!-- Menu --&gt;
		 &lt;div class=&rdquo;menu&rdquo;&gt;
				&lt;ul&gt;
					 &lt;li&gt;&lt;a href=&rdquo;#&rdquo;&gt;Prev&lt;/a&gt;&lt;/li&gt;
					 &lt;li&gt;&lt;a href=&rdquo;#&rdquo;&gt;Next&lt;/a&gt;&lt;/li&gt;
				&lt;/ul&gt;
		 &lt;/div&gt;
	&lt;/div&gt;

</pre>
<p>A continuaci&oacute;n, vamos a destacar una serie de consejos que deber&iacute;an de cumplir todos los SLIDERs.</p>
<h3>Programaci&oacute;n en jQuery</h3>
<p>Utlizando clases en lugar de IDs para referenciar a los SLIDERs podemos utilizar la siguiente t&eacute;cnica en jQuery para automatizar el comportamiento de todos ellos.</p>
<pre class="code">// Slider
$('.slider').each (function ())
{
	// Declaraci&oacute;n de variables
	var slider = this ;


	// C&oacute;digo del Slider
	// &hellip;
}
</pre>
<p>Esto nos permite dise&ntilde;ar el comportamiento b&aacute;sico de todos ellos sin tener que programarlos uno a uno.</p>
<h3>Utilizando el .animate de jQuery</h3>
<p>El m&eacute;todo de animaci&oacute;n m&aacute;s recomendado es animar el posicionamiento del elemento respecto al contenedor. (<em>la posici&oacute;n left o top, cuando sea un slider horizontal o vertical, respectivamente</em>).</p>
<p>L&oacute;gicamente, para esto, nuestro contenedor tiene que tener posicionamiento relativo y el listado posicionamiento absoluto.</p>
<pre class="code">.slider .contendor {
	 position: relative;
}

.slider .contenedor ul {
	position: absolute;
	top: 0;
	left: 0;

	/* 
	 * Valor muy alto para permitir almacenar todos los elementos 
	 * Este valor deber&iacute;a ser height para sliders verticales 
	 */
	width: 10000px;
}
</pre>
<blockquote style="background-color: #ccc; border: 1px solid #333; margin: 7px; font-style: italic;">Para m&aacute;s informaci&oacute;n sobre posicionamiento, consulte <a href="http://www.librosweb.es/css/capitulo5.html" target="_blank">este art&iacute;culo</a></blockquote>
<p>En el caso de sliders horizontales o verticales de tama&ntilde;o fijo, donde cada item tiene el mismo tama&ntilde;o, la forma m&aacute;s sencilla de animar es la siguiente:</p>
<ol>
<li> <strong>Sacar el n&uacute;mero de elementos en total</strong>
<pre class="code">			var numElementos = $(slider).find ('.contenedor ul li').size () ;
		</pre>
</li>
<li> <strong>Calcular la distancia entre dos elementos</strong><br /> El mejor m&eacute;todo para calcular esto es calcular la diferencia de posicionamiento entre el segundo elemento y el primero
<p>De esta forma, tenemos la distancia absoluta, sin tener que preocuparnos de m&aacute;rgenes, rellenos y la diferencia de c&oacute;mo se interpretan estos valores dependiendo del navegador.</p>
<pre class="code">			var distancia = 
				$(slider).find ('li:first-child + li').position().left - 
				$(slider).find ('li:first-child').position().left ;
		</pre>
<p><strong style="color: red;">&iexcl;Atenci&oacute;n!</strong> Si nos fijamos bien, es posible que el c&oacute;digo anterior nos de un  			error en el caso de que haya menos de 2 elementos. Afortunadamente, en este caso, la l&oacute;gica nos indica que un  			SLIDER no tiene ninguna funci&oacute;n en este caso, por lo que lo m&aacute;s l&oacute;gico es desactivarlo antes.</p>
<pre class="code">			// Slider
			$('.slider').each (function ())
			{
				// Declaraci&oacute;n de variables
				var slider = this ;
				var numElementos = 
				$(slider).find ('.contenedor ul li').size () ;


				// &iquest;Es necesario un Slider?
				if (numElementos &lt; 2)
				{
					return ;
				}


				// C&oacute;digo del slider
				// ...
			}
		</pre>
</li>
<li> <strong>Calcular el n&uacute;mero de elementos visibles. </strong><br /> Que se puede calcular dividiendo el ancho (o alto) del contenedor entre la distancia entre los elementos. </li>
<li> <strong>Inicializar el paginador a 1</strong> </li>
</ol>
<p>Cada vez que el usuario pulse sobre los botones de anterior y siguiente, entonces se calcula la posici&oacute;n left multiplicando la p&aacute;gina actual por el ancho. Adem&aacute;s, hay que actualizar el paginador aument&aacute;ndolo o disminuy&eacute;ndolo en una unidad seg&uacute;n avancemos o retrodedamos.</p>
<p>Un ejemplo de la animaci&oacute;n del listado de elementos es el siguiente:</p>
<pre class="code">// &hellip;

// Siguiente
$(this).find ('.next').click (function (e)
{
	// Evitamos el comportamiento del enlace
	e.preventDefault () ;
				

// Si hay m&aacute;s elementos a la derecha
	if (page &lt; (numItems - numItemsVisible))
	{
		page++;
		$(slider).find ('ul').stop().animate ({left:"-" + (myWidth * (page - 1) + 'px')}, velocity) ;	
	}
}) ;
			
			
// Anterior
$(this).find ('.prev').click (function (e)
{
	// Evitamos el comportamiento del enlace
	e.preventDefault () ;
				
		
	// S&oacute;lo si hay elementos a la izquierda
	if (page &gt; 1)
	{
		page--;
		$(slider).find ('ul').stop().animate ({left: "-" + (myWidth * (page - 1) + 'px')}, velocity) ;	
	}
}) ;	

// &hellip;
</pre>
<p>Otra cosa importante a tener en cuanta cuando realizamos la animaci&oacute;n es la siguiente. Como estamos indicando la nueva posici&oacute;n del elemento de forma absoluta podemos realizar lo siguiente:</p>
<pre class="code">	$(slider).find ('ul').stop().animate ({ &hellip; }) ;
</pre>
<p>Con <strong>STOP</strong> estamos indicando que cualquier animaci&oacute;n que hubiera previamente debe detenerse y s&oacute;lo hacer caso a la nueva, de forma que no se van quedando las animaciones en cola y s&oacute;lo tiene valor la &uacute;ltima que ha pulsado el usuario.</p>
<h3>Desactivar el men&uacute; si no hay elementos suficientes para realizar la animaci&oacute;n</h3>
<p>Una buena pr&aacute;ctica es desactivar el men&uacute; de navegaci&oacute;n cuando el n&uacute;mero de elementos totales es inferior o igual al n&uacute;mero de elementos visibles.</p>
<pre class="code">if (numElementos &lt;= numVisible)
{
	$(slider).find (".menu").hide () ;
}
</pre>
<h3>Comportamiento autom&aacute;tico</h3>
<p>Con el plugin de <a href="http://jquery.offput.ca/every/" target="_blank">timer.js</a> es posible hacer que el slider avance  	autom&aacute;ticamente Utilizando adem&aacute;s atributos &ldquo;data-&rdquo; de HTML podemos especificar atributos al Slider para que se  	desactive este comportamiento autom&aacute;tico una vez que el usuario realiza una acci&oacute;n manual sobre el Slider.</p>
<p>Por ejemplo&hellip; podemos a&ntilde;adir un atributo al comenzar cada Slider</p>
<pre class="code">$('.slider').each (function ())
{
	// Vars
	var slider = this ;

	// Definir la acci&oacute;n del men&uacute;
	$(slider).attr ('data-automatic', 1); 


	// Comportamiento autom&aacute;tico
	$(slider).everyTime (5000, function() 
	{
		// &iquest;Est&aacute; activado el comportamiento autom&aacute;tico?
		if ($(slider).attr ('data-automatic') == '1')
		{
			// C&oacute;digo de animaci&oacute;n
		}
 	}
 
	// En las acciones del men&uacute; lo desactivamos
	$(slider).find ('menu a').click (function (e)
	{
		$(slider).attr ('data-automatic', 0); 
	}) ;
}
</pre>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=88</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/programando-un-pasador-o-slider-con-jquery-y-css.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Diferencias entre JOIN, LEFT JOIN y RIGHT JOIN</title>
			<link>http://www.imaginanet.com/blog/diferencias-entre-join-left-join-y-right-join.html</link>
			<guid>http://www.imaginanet.com/blog/diferencias-entre-join-left-join-y-right-join.html</guid>
			<comments>http://www.imaginanet.com/blog/diferencias-entre-join-left-join-y-right-join.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Thu,  1 Dec 2011 01:56:08 +0100</pubDate>
					<category><![CDATA[MySQL]]></category>
					<description><![CDATA[Suele ser muy com&uacute;n confundirse con las distintas combinaciones que se pueden realizar entre tablas, por ello vamos a aclarar las diferencias entre cada una.
Existen las combinaciones internas de tablas donde cada registro de la tabla A se combina con otro de la tabla B que cumpla las condiciones.Ej: Obtener los empleados...]]></description>
			<content:encoded><![CDATA[><p>Suele ser muy com&uacute;n confundirse con las distintas combinaciones que se pueden realizar entre tablas, por ello vamos a aclarar las diferencias entre cada una.</p>
<p>Existen las <strong>combinaciones internas</strong> de tablas donde cada registro de la tabla A se combina con otro de la tabla B que cumpla las condiciones.<br /><em>Ej: Obtener los empleados del departamento de recursos humanos:</em></p>
<pre class="code">select * from empleados a, departamentos b where a.id_departamento=b.id</pre>
<p>Esta consulta anterior se podr&iacute;a haber expresado de forma explic&iacute;ta as&iacute;:</p>
<pre class="code">select * from empleados a inner join departamentos b on a.id_departamento=b.id</pre>
<p>Este tipo de combinaciones de tabas suele ser la m&aacute;s utilizada, pero si por ejemplo queremos un listado de todos los empleados, que tengan o no departamento asignado, entonces debemos realizar lo que se llama una <strong>combinaci&oacute;n externa</strong>.<br /><em>Ej: Obtener todos los empleados tengan o no departamento asignado:</em></p>
<pre class="code">select * from empleados a left join departamentos b on a.id_departamento=b.id</pre>
<p>De esta forma se realizada un outer join por la izquierda, es decir nos traemos todos los registros de la tabla izquierda tengan o no correspondencia con la tabla derecha. Por el lado contrario un right join hace lo mismo pero trayendo todos los registros de la tabla derecha tengan o no correspondencia con la de la izquierda. Aquellos registros sin correspondencia entren para el campo correspondiente un valor NULL, es decir si un empleado no tiene departamento, entonces su valor es null.</p>
<p>Los ejemplos que hemos visto hasta ahora se pueden aplicar en MySQL y otros compatibles, pero en Oracle para realizar los outer join se realizan as&iacute;:</p>
<pre class="code">select * from empleados a, departamentos b where a.id_departamento(+)=b.id</pre>
<p>Es decir se coloca el (+) en el lado que queramos (left o right).</p>
<p>En los left o right join se puede ademas aplicar otras condiciones.<br />Ej: Obtener los empleados de los departamentos que tengan hipoteca:</p>
<pre class="code">select * from empleados a left join departamentos b on a.id_departamento=b.id where a.hipoteca=1</pre>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=87</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/diferencias-entre-join-left-join-y-right-join.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Crear certificados digitales con OpenSSL</title>
			<link>http://www.imaginanet.com/blog/crear-certificados-digitales-con-openssl.html</link>
			<guid>http://www.imaginanet.com/blog/crear-certificados-digitales-con-openssl.html</guid>
			<comments>http://www.imaginanet.com/blog/crear-certificados-digitales-con-openssl.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Wed, 30 Nov 2011 18:23:05 +0100</pubDate>
					<category><![CDATA[Servidores y Seguridad]]></category>
					<category><![CDATA[Java]]></category>
					<category><![CDATA[PHP]]></category>
					<description><![CDATA[Cuando queremos programar o usar alguna aplicaci&oacute;n que requiera autenticaci&oacute;n y encriptaci&oacute;n podemos hacer uso de certificados digitales. Para obtenerlo podemos hacer uso de un certificado obtenido mediante VeriSign, DNI electr&oacute;nico o crear nosotros uno mismo.
En esta entrada de blog vamos a hacer esta...]]></description>
			<content:encoded><![CDATA[><p>Cuando queremos programar o usar alguna aplicaci&oacute;n que requiera autenticaci&oacute;n y encriptaci&oacute;n podemos hacer uso de certificados digitales. Para obtenerlo podemos hacer uso de un certificado obtenido mediante VeriSign, DNI electr&oacute;nico o crear nosotros uno mismo.</p>
<p>En esta entrada de blog vamos a hacer esta &uacute;ltima opci&oacute;n, que aunque  no  podr&aacute; ser verificado por ninguna Autoridad Certificadora (CA), nos   servir&aacute; perfectamente mientras realizamos el desarrollo.</p>
<p>Antes de empezar, vamos a suponer que tenemos claros los conceptos del certificado digital, tales como:</p>
<ul>
<li><a title="Criptograf&iacute;a asim&eacute;trica" href="http://es.wikipedia.org/wiki/Criptograf%C3%ADa_asim%C3%A9trica" target="_blank">Concepto de clave p&uacute;blica privada </a></li>
<li><a title="Certificado digital" href="http://es.wikipedia.org/wiki/Certificado_digital" target="_blank">Certificado digital</a></li>
<li><a title="Autoridad certificadora" href="http://es.wikipedia.org/wiki/Autoridad_de_certificaci%C3%B3n">Autoridad certificadora</a></li>
</ul>
<p>Tambi&eacute;n ser&aacute; necesario tener claro algunos conceptos muy b&aacute;sicos de Linux como moverse por archivos, permisos, edici&oacute;n, etc.</p>
<ul>
</ul>
<h3>Instalar OpenSSL</h3>
<p>Para empezar, necesitaremos OpenSSL instalado a ser posible la  versi&oacute;n m&aacute;s actualizada posible, ya que si no, puede ser que alguno de  los pasos no funcione correctamente.</p>
<p>En Windows lo descargaremos y descomprimiremos y en Linux para Ubuntu/Debian:</p>
<pre class="code">sudo apt-get install openssl</pre>
<p>o para RedHat / CentOS:</p>
<pre class="code">yum install openssl</pre>
<p>lo tendremos instalado.</p>
<h3>Crear autoridad certificadora de certificados X.509</h3>
<p>Prepararemos el entorno:</p>
<pre class="code">cd $HOME
mkdir CA
cd CA
mkdir certificados
mkdir privado
echo '01' &gt; contador
touch certindex</pre>
<p>Ahora generaremos el archivo de configuraci&oacute;n OpenSSL</p>
<pre class="code">nano openssl.cnf
</pre>
<p>El contenido deber&iacute;a ser algo as&iacute;:</p>
<pre class="code"># -----------------------
# Configuraci&oacute;n inicial
# -----------------------

dir           = .    # Directorio de trabajo

[ ca ]
default_ca    = CA_default

[ CA_default ]
serial        = $dir/contador          # Contador de n&uacute;meros de serie
database      = $dir/certindex         # Listado de certificados
new_certs_dir = $dir/certificados      # Directorio para los certificados generados
certificate   = $dir/cacert.pem        # Certificado ra&iacute;z
private_key   = $dir/privado/cakey.pem # Clave privada del certificado ra&iacute;z
default_md    = sha1                   # Digest usado
preserve      = no                     # Preserva el orden de los campos del DN
nameopt       = default_ca             # Muestra detalles del certificado
certopt       = default_ca             # Muestra detalles del certificado
policy        = policy_match           # Indica si los campos obligatorios  y/o
                                       # opcionales deben ser iguales al 
                                       # certificado ra&iacute;z

# Pol&iacute;tica de recolecci&oacute;n de datos frente al ra&iacute;z
[ policy_match ]
countryName                 = match        
stateOrProvinceName         = match          
organizationName            = match
organizationalUnitName      = optional      
commonName                  = supplied     
emailAddress                = optional

# Configuraci&oacute;n de certificados
[ req ]
default_bits       = 2048           # Tama&ntilde;o de la clave en bits
default_keyfile    = key.pem        # Fichero de la clave privada
default_md         = sha1           # Digest
string_mask        = nombstr        # Caracteres permitidos en la clave
distinguished_name = req_distinguished_name  # Secci&oacute;n para el nombre DN
req_extensions     = v3_req         # Secci&oacute;n con mas extensiones que se 
                                    # a&ntilde;aden a la petici&oacute;n del 
                                    # certificado

# Distinguished Name. Datos p&uacute;blicos del certificado X.509 que identifican al propietario.
[ req_distinguished_name ]
0.organizationName          = Nombre de la organizaci&oacute;n
0.organizationName_default  = Imaginanet
organizationalUnitName      = Departamento
emailAddress                = Correo electr&oacute;nico
emailAddress_max            = 40
localityName                = Ciudad
stateOrProvinceName         = Estado o provincia
countryName                 = C&oacute;digo ISO del pais (dos letras)
countryName_default         = ES
countryName_min             = 2
countryName_max             = 2
commonName                  = Nombre com&uacute;n (nombre del host o IP)
commonName_max              = 64

# Si se indica la opcion -x509 indica que se trata de un certificado CA ra&iacute;z
# con autoridad para firmar o revocar otros certificados
[ v3_ca ]
basicConstraints       = CA:TRUE  
                                 
subjectKeyIdentifier   = hash     
authorityKeyIdentifier = keyid:always,issuer:always  

[ v3_req ]
basicConstraints            = CA:FALSE
subjectKeyIdentifier        = hash 
</pre>
<br />Finalmente ejecutamos<br />
<pre class="code">openssl req -new -x509 -extensions v3_ca -keyout privado/cakey.pem  -out cacert.pem -days 3650 -config ./openssl.cnf
</pre>
<h3>Creando un certificado digital X.509 en base a nuestra autoridad certificadora</h3>
<pre class="code">openssl req -new -nodes -out imaginanet-cert.pem -config ./openssl.cnf

openssl ca -out certificado-imaginanet.pem -config ./openssl.cnf -days 3650  -infiles imaginanet-cert.pem
</pre>
<p>Donde el archivo <em>imaginanet-cert.pem</em> corresponde a nuestra clave privada y <em>certificado-imaginanet.pem</em> a la p&uacute;blica.</p>
<h3>Utilidades</h3>
<p>No debemos olvidar que los certificados generados no ser&aacute;n validos en un entorno real de producci&oacute;n ya que nuestra CA no ser&aacute; reconocida por los navegadores o el KeyStore de Java, pero si que nos vendr&aacute; bien como entorno de desarrollo para:</p>
<ul>
<li>Poner un servidor web en modo seguro HTTPS</li>
<li>Realizar firmas sobre ficheros o correos mediante cualquier lenguaje de programaci&oacute;n</li>
</ul>
<h3>A&ntilde;adiendo la autoridad certificadora y nuestro certificado digital a nuestro navegador: Firefox</h3>
<p>Supongamos que hemos puesto en marcha nuestro servidor web Apache con HTTPS y el certificado digital creado. Para que el navegador nos confirme que es una p&aacute;gina v&aacute;lida deberemos <span style="text-decoration: underline;">a&ntilde;adir la autoridad certificadora</span> a la lista de autoridades certificadoras v&aacute;lidas. En el caso de Firefox:</p>
<p><em>Editar -&gt; Preferencias -&gt; Avanzado -&gt; Cifrado -&gt; Ver certificados -&gt; Autoridades -&gt; Importar</em></p>
<p>y seleccionaremos el archivo <em>cacert.pem</em></p>
<p>Si por el contrario quisi&eacute;ramos firmar digitalmente con el certificado creado, deberemos <span style="text-decoration: underline;">a&ntilde;adir el certificado digital</span> yendo a:</p>
<p><em>Editar -&gt; Preferencias -&gt; Avanzado -&gt; Cifrado -&gt; Ver certificados -&gt; Sus certificados -&gt; Importar</em></p>
<p>y seleccionar la clave privada <em>imaginanet-cert.pem</em> e introducir la contrase&ntilde;a para ser guardada en el KeyStore de Firefox.<em></em></p>
<p>Todo documento firmado con este certificado ser&aacute; no v&aacute;lido ya que el servidor que lo firme no reconocer&aacute; a la autoridad certificadora, pero podemos a&ntilde;adir dicho certificado al KeyStore del lado del servidor, cosa que veremos en pr&oacute;ximas entradas del blog.<em><br /></em></p>
<ul>
</ul>
<h3>Convertir certificados .pem / .cert (X.509) a .pfx (PKCS12)</h3>
<p>En ocasiones es necesario el uso de certificados en formato PKCS12 de extensi&oacute;n PFX, como por ejemplo para la librer&iacute;a <a title="Librer&iacute;a PDF para Java / C#" href="http://itextpdf.com/" target="_blank">iText</a> para Java / C#. Lo podemos hacer mediante el siguiente comando con OpenSSL 0.9.8k (si tenemos una versi&oacute;n inferior deberemos actualizar ya que no funciona en todas las aplicaciones el fichero generado):</p>
<pre class="code">openssl pkcs12 -inkey private_key.pem -in public_cert.cert -export -out cert.pfx
</pre>
<h3>Referencias</h3>
<p>Parte de este art&iacute;culo se ha basado en <a href="http://www.linuxtotal.com.mx/ssl_apache.html" target="_blank">http://www.linuxtotal.com.mx/ssl_apache.html</a></p>
<p>M&aacute;s informaci&oacute;n:</p>
<ul>
<li><a title="X.509" href="http://es.wikipedia.org/wiki/X.509">X.509</a></li>
<li><a title="PKCS" href="http://en.wikipedia.org/wiki/PKCS">PKCS7</a></li>
<li><a title="PKCS12" href="http://en.wikipedia.org/wiki/PKCS12">PKCS12</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=86</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/crear-certificados-digitales-con-openssl.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Centrar verticalmente contenidos con CSS</title>
			<link>http://www.imaginanet.com/blog/centrar-verticalmente-contenidos-con-css.html</link>
			<guid>http://www.imaginanet.com/blog/centrar-verticalmente-contenidos-con-css.html</guid>
			<comments>http://www.imaginanet.com/blog/centrar-verticalmente-contenidos-con-css.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Mon,  1 Aug 2011 09:11:30 +0100</pubDate>
					<category><![CDATA[XHTML]]></category>
					<category><![CDATA[CSS]]></category>
					<description><![CDATA[A veces no resulta tan trivial conseguir que nuestros contenidos se centren verticalmente, es por ello que vamos a explicar como llevar dicha a cabo dicha tarea de una forma sencilla.  Antes de nada repasemos como funciona el centrado de contenidos horizontalmente: Al elemento contenedor le ponemos la propiedad...]]></description>
			<content:encoded><![CDATA[>A veces no resulta tan trivial conseguir que nuestros contenidos se centren verticalmente, es por ello que vamos a explicar como llevar dicha a cabo dicha tarea de una forma sencilla.<br /> <br /> Antes de nada repasemos como funciona el <em>centrado de contenidos horizontalmente</em>:<br /> Al elemento contenedor le ponemos la propiedad &ldquo;text-align&rdquo; con valor &ldquo;center&rdquo; y los elementos interiores se centran. Ahora bien este centrado solo funciona con elementos inline, si lo que queremos es centrar bloques, entonces debemos utilizar la propiedad &ldquo;margin&rdquo; con valores &ldquo;0 auto&rdquo; en los elementos interiores, es decir no en el elemento contenedor como en el caso anterior. De esta forma conseguimos el centrado horizontal para elementos con &ldquo;display&rdquo; con valor &ldquo;block&rdquo;.<br /> <br /> En el caso del <em>centrado vertical</em> no nos vale la propiedad margin con valores auto como en el caso horizontal. Por ejemplo si lo que queremos es centrar un texto dentro de un elemento contenedor que tiene altura 20px, entonces una solucion sencilla es indicar que dicho texto tiene una altura de linea de 20px. Es decir poner la propiedad &ldquo;line-height&rdquo; con valor &ldquo;20px&rdquo;.<br /> <br /> Ahora bien imaginemos que queremos centrar verticalmente una foto dentro de un elemento contenedor, como puede ser una etiqueta &ldquo;div&rdquo;. La foto tiene 100px de altura, y el contenedor 300px. Bien para lograr que la foto se centre verticalmente, debemos a&ntilde;adir un elemento dentro de la capa contenedora. Dicho elemento va a tener una altura de 300px (la misma que la capa contenedora), una anchura de 1px, un margen derecho de -1px, un display de bloque en l&iacute;nea, y una alineaci&oacute;n vertical media. A su vez la imagen va a tener una alineaci&oacute;n vertical media.<br /><br />
<pre class="code"><div style="background: cyan; height: 400px;">
&lt; span style=" display: inline-block; margin-right: -1px; vertical-align: middle; height:
400px; width: 1px; "&gt;&lt; /span&gt;<img alt="" />
</div>
</pre>
Como conclusi&oacute;n decir, que para centrar verticalmente necesitamos tener dos elementos dentro de la capa contenedora, para que se centren uno respecto del otro.]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=85</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/centrar-verticalmente-contenidos-con-css.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Bases de datos NOSQL y PHP</title>
			<link>http://www.imaginanet.com/blog/bases-de-datos-nosql-y-php.html</link>
			<guid>http://www.imaginanet.com/blog/bases-de-datos-nosql-y-php.html</guid>
			<comments>http://www.imaginanet.com/blog/bases-de-datos-nosql-y-php.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Sat, 30 Jul 2011 23:10:20 +0100</pubDate>
					<category><![CDATA[PHP]]></category>
					<category><![CDATA[Internet]]></category>
					<category><![CDATA[Redes Sociales]]></category>
					<category><![CDATA[Web 2.0]]></category>
					<description><![CDATA[El t&eacute;rmino NOSQL aplicado a bases de datos no se refiere a que no se utilice el lenguaje sql, si no que significa "not only sql". Estas bases de datos son no relacionales y no proporcionan garant&iacute;as ACID, tampoco suelen tener esquemas fijos de tablas ni sentencias join. El t&eacute;rmino ACID hace referencia a un...]]></description>
			<content:encoded><![CDATA[><p>El t&eacute;rmino NOSQL aplicado a bases de datos no se refiere a que no se utilice el lenguaje sql, si no que significa "not only sql". Estas bases de datos son no relacionales y no proporcionan garant&iacute;as ACID, tampoco suelen tener esquemas fijos de tablas ni sentencias join. El t&eacute;rmino ACID hace referencia a un conjunto de caracter&iacute;sticas requeridas para que una serie de instrucciones puedan ser consideradas como una transacci&oacute;n.</p>
<p>Estas bases de datos tienen la ventaja de su rapidez y escalabilidad horizontal y los inconvenientes de que no garantizan las transacciones. Dependiendo del tipo de proyecto, puede que se adapte mejor una base de datos de este tipo o una relacional, todo depende de las necesidades del proyecto.</p>
<p>En PHP nos encontramos con distintos productos que utilizan esta tecnolog&iacute;a, las m&aacute;s conocidas son de tipo documental y de tipo clave-valor. Bases de datos documentales tenemos por ejemplo CouchDB y MongoDB, en cuando a bases de datos de tipo clave-valor quiz&aacute;s la m&aacute;s conocida sea Cassandra, creada por y para Facebook. Todas estos ejemplos son de c&oacute;digo abierto.</p>
<p>En este art&iacute;culo nos centraremos en MongoDB, una bases de datos de tipo documental en la que los datos se guardan en disco en formato BSON (JSON binario). Es muy sencillo trabajar con ella, al no tener que definir esquemas fijos, la l&oacute;gica del modelo es la que establece como se guardan los datos. En una misma tabla podemos tener datos con distintos formatos, lo que demuestra la potencia de esta tecnolog&iacute;a. Otra de sus virtudes es la facilidad con la que se puede escalar sin apenas configurar nada, simplemente a&ntilde;adiendo nodos nuevos. Si se prev&eacute; que una aplicaci&oacute;n vaya a ser usada por multitud de usuarios a la vez y las transacciones no sean un problema, seguramente esta sea la soluci&oacute;n adecuada.</p>
<p>Veamos un ejemplo de utilizaci&oacute;n del driver de mongodb para php, con las operaciones b&aacute;sicas.</p>
<pre class="code php">	$m = new Mongo(); // connect
	$db = $m-&gt;selectDB("example");
	$collection = $db-&gt;users;

	// A&ntilde;adir un registro
	$obj = array( "username" =&gt; "Pedro", "password" =&gt; md5("mipassword") );
	$collection-&gt;insert($obj);


	// A&ntilde;adir otro registro con un esquema diferente
	$obj = array( "username" =&gt; "Juan", "password" =&gt; md5("otropassword"), "year" =&gt; "1960" );
	$collection-&gt;insert($obj);

	// Buscar todos los elementos de la coleccion
	$cursor = $collection-&gt;find();

	// Iterar a trav&eacute;s de los resultados
	foreach ($cursor as $obj) {
		echo $obj["username"] . "\n";
	}

	// Buscar el usuario con nombre Juan
	$user = $collection-&gt;findOne(array('username' =&gt; 'Juan')));

	// Buscar usuarios con el campo a&ntilde;o  &gt; 1950
	$users = $collection-&gt;find(array('year' =&gt; array( '$gt' =&gt; 1950)));


	// Usar javascript para reducir un resultado, conseguiremos los usuarios que se llamen juan o que su a&ntilde;o sea &lt; 1950
	$js = "function() {
		return this.username == 'Juan' || this.year &lt; 1950;
	}";
	$users = $collection-&gt;find(array('$where' =&gt; $js));

</pre>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=84</wfw:commentRss>
			<slash:comments>1</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/bases-de-datos-nosql-y-php.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Crear thumbnails (miniaturas) con php al vuelo.</title>
			<link>http://www.imaginanet.com/blog/crear-thumbnails-miniaturas-con-php-al-vuelo.html</link>
			<guid>http://www.imaginanet.com/blog/crear-thumbnails-miniaturas-con-php-al-vuelo.html</guid>
			<comments>http://www.imaginanet.com/blog/crear-thumbnails-miniaturas-con-php-al-vuelo.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Mon, 11 Jul 2011 21:45:36 +0100</pubDate>
					<category><![CDATA[PHP]]></category>
					<category><![CDATA[XHTML]]></category>
					<description><![CDATA[Para reducir el ancho de banda en nuestro servidor, a costa de cargar la cpu un poco más, podemos redimensionar las imágenes que estamos sirviendo con un sencillo script de PHP. Vamos a ver dos métodos, uno con la librería gd y otro llamando a imagemagick.
Librería GD:
Usaremos un archivo php para hacer la carga de las...]]></description>
			<content:encoded><![CDATA[><p>Para reducir el ancho de banda en nuestro servidor, a costa de cargar la cpu un poco más, podemos redimensionar las imágenes que estamos sirviendo con un sencillo script de PHP. Vamos a ver dos métodos, uno con la librería gd y otro llamando a imagemagick.</p>
<h2>Librería GD:</h2>
<p>Usaremos un archivo php para hacer la carga de las imágenes, lo llamaremos thumb.php y lo colocaremos en la raíz de nuestra web. Lo llamaremos de la siguiente forma:</p>
<pre class="code php">
        &lt;img src="/thumb.php?file=/public/image1.png&amp;width=100" alt="miniatura" /&gt;
</pre>
<p>Le pasamos 2 parámetros al script:</p>
<p><strong>file</strong>: la ruta a la imagen que queremos redimensionar.</p>
<p><strong>width</strong>: la nueva anchura.</p>
<p>Lo primero que tenemos que hacer el calcular las nuevas dimensiones de la imagen, en nuestro ejemplo estamos marcando la anchura, y la altura se calcula a partir de ésta. Cuando ya tenemos las nuevas dimensiones vemos en qué formato está y luego escribimos las cabeceras correspondientes y la mostramos. El código del archivo thumb.php sería el siguiente:</p>
<pre class="code php">
        $file = $_GET["file"];
        $width = $_GET["width"];

        // Ponemos el . antes del nombre del archivo porque estamos considerando que la ruta está a partir del archivo thumb.php
        $file_info = getimagesize("." . $file);
        // Obtenemos la relación de aspecto
        $ratio = $file_info[0] / $file_info[1];

        // Calculamos las nuevas dimensiones
        $newwidth = $width;
        $newheight = round($newwidth / $ratio);
        
        // Sacamos la extensión del archivo
        $ext = explode(".", $file);
        $ext = strtolower($ext[count($ext) - 1]);
        if ($ext == "jpeg") $ext = "jpg";

        // Dependiendo de la extensión llamamos a distintas funciones
        switch ($ext) {
                case "jpg":
                        $img = imagecreatefromjpeg("." . $file);
                break;
                case "png":
                        $img = imagecreatefrompng("." . $file);
                break;
                case "gif":
                        $img = imagecreatefromgif("." . $file);
                break;
        }
        // Creamos la miniatura
        $thumb = imagecreatetruecolor($newwidth, $newheight);
        // La redimensionamos
        imagecopyresampled($thumb, $img, 0, 0, 0, 0, $newwidth, $newheight, $file_info[0], $file_info[1]);
        // La mostramos como jpg
        header("Content-type: image/jpeg");
        imagejpg($thumb, null, 80);
</pre>
<br />
<h2>Imagemagick</h2>
<p>Si usamos imagemagick tenemos las ventajas de ahorrar consumo de memoria y los inconvenientes de que tenemos que tenerlo instalado en nuestro servidor. En caso de tenerlo disponible, el script resultante sería muy parecido al anterior</p>
<pre class="code php">
        $file = $_GET["file"];
        $width = $_GET["width"];

        // Ponemos el . antes del nombre del archivo porque estamos considerando que la ruta está a partir del archivo thumb.php
        $file_info = getimagesize("." . $file);
        // Obtenemos la relación de aspecto
        $ratio = $file_info[0] / $file_info[1];

        // Calculamos las nuevas dimensiones
        $newwidth = $width;
        $newheight = round($newwidth / $ratio);

        // No necesitamos sacar la extensión ya que el comando convert ya detecta el formato
        header("Content-type: image/jpeg");
        passthru("convert -scale ".($newwidth)."x".($newheight)."! "./".$file."" JPG:-");
</pre>
<br /><br />]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=83</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/crear-thumbnails-miniaturas-con-php-al-vuelo.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Cambio de divisas mediante el Banco Central Europeo</title>
			<link>http://www.imaginanet.com/blog/cambio-de-divisas-mediante-el-banco-central-europeo.html</link>
			<guid>http://www.imaginanet.com/blog/cambio-de-divisas-mediante-el-banco-central-europeo.html</guid>
			<comments>http://www.imaginanet.com/blog/cambio-de-divisas-mediante-el-banco-central-europeo.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Mon, 11 Jul 2011 11:15:45 +0100</pubDate>
					<category><![CDATA[Comercio electrónico]]></category>
					<category><![CDATA[PHP]]></category>
					<description><![CDATA[Si hacemos uso de distintas monedas en nuestra p&aacute;gina web para mostrar precios orientativos, necesitaremos mantener actualizado el cambio de moneda por la fluctuaci&oacute;n diaria entre euros, d&oacute;lares, yenes, etc.
El Banco Central Europeo genera un archivo XML que es actualizado a diario. Este XML lo podemos...]]></description>
			<content:encoded><![CDATA[><p>Si hacemos uso de distintas monedas en nuestra p&aacute;gina web para mostrar precios orientativos, necesitaremos mantener actualizado el cambio de moneda por la fluctuaci&oacute;n diaria entre euros, d&oacute;lares, yenes, etc.</p>
<p>El Banco Central Europeo genera un archivo XML que es actualizado a diario. Este XML lo podemos procesar y actualizar nosotros para guardarlo en un archivo de configuraci&oacute;n o base de datos mediante SimpleXML y una tarea programada / cron.</p>
<p>El c&oacute;digo PHP haciendo uso de SimpleXML ser&iacute;a el siguiente:</p>
<pre class="code php">$xml = simplexml_load_file("http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml");
foreach ($xml-&gt;Cube-&gt;Cube-&gt;Cube as $c) {
	$attr = $c-&gt;attributes();
	echo "Un euro equivale a ".$attr[1]." ".$attr[0]."<br />";
}
</pre>
<p>Donde la variable $attr[0] equivale el c&oacute;digo ISO de la moneda y $attr[1] equivale al valor de un euro en dicha moneda.<br /><br />A partir de aqu&iacute;, deberemos procesar el valor de la moneda como nos interese.</p>
<p><strong>M&aacute;s informaci&oacute;n:</strong></p>
<ul>
<li><a title="Cambio de divisas" href="http://www.ecb.int/stats/exchange/eurofxref/html/index.en.html" target="_blank">Informaci&oacute;n para desarrolladores del Banco Central Europeo</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=82</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/cambio-de-divisas-mediante-el-banco-central-europeo.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Redireccionar dominios con .htaccess</title>
			<link>http://www.imaginanet.com/blog/redireccionar-dominios-con-htaccess.html</link>
			<guid>http://www.imaginanet.com/blog/redireccionar-dominios-con-htaccess.html</guid>
			<comments>http://www.imaginanet.com/blog/redireccionar-dominios-con-htaccess.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Mon,  4 Jul 2011 12:23:24 +0100</pubDate>
					<category><![CDATA[SEO]]></category>
					<category><![CDATA[Buscadores]]></category>
					<description><![CDATA[Suele ser com&uacute;n que una web tenga varios dominios apuntando a ella, como .es, .com, .net, etc. y que solo nos interese mostrar siempre el mismo dominio, independientemente del que teclee el usuario, por ejemplo el .com (o cualquier otro), o que a su vez google solo indexe direcciones del dominio elegido.  Suponemos que...]]></description>
			<content:encoded><![CDATA[>Suele ser com&uacute;n que una web tenga varios dominios apuntando a ella, como .es, .com, .net, etc. y que solo nos interese mostrar siempre el mismo dominio, independientemente del que teclee el usuario, por ejemplo el .com (o cualquier otro), o que a su vez google solo indexe direcciones del dominio elegido.<br /> <br /> Suponemos que nuestra web se encuentra alojada en un servidor con apache y con el mod-rewrite activo, y que por tanto podemos editar el fichero .htaccess que se encuentra en la ra&iacute;z de nuestra web.<br /> <br /> Lo primero es a&ntilde;adir la siguiente l&iacute;nea a nuestro .htaccess, para activar el motor de reescritura de direcciones:<br />
<pre class="code">RewriteEngine On
</pre>
Ahora vamos a ir explicando cada caso particular con ejemplos, donde nuestro dominio principal sera &ldquo;midominio.com&rdquo;. Por ejemplo si lo que queremos es que cualquier persona que teclee nuestro dominio sin la triple w (como midominio.com), le aparezca autom&aacute;ticamente la direcci&oacute;n con las tres w (www.midominio.com), debemos hacer lo siguiente:<br />
<pre class="code">RewriteCond %{HTTP_HOST} ^midominio.com$ [NC]
RewriteRule ^(.*)$ http://www.midominio.com/ [R=301,L]
</pre>
De esta forma indicamos una condici&oacute;n con la sentencia RewriteCond, para que cuando el dominio recibido, indicado por la variable de servidor HTTP_HOST, se corresponda con midominio.com, siendo la comprobaci&oacute;n insensitiva, es decir ignorando may&uacute;sculas o min&uacute;sculas, entonces se ejecute las reglas siguientes indicadas por sentencias RewriteRule. Es decir, cuando se cumple una condici&oacute;n se ejecutan todas las reglan que la preceden hasta encontrar una regla que lleve el flag L, el cu&aacute;l indica que es la &uacute;ltima regla. En nuestro caso solo necesitamos una regla, por ello le incluimos el flag L, y lo que hace dicha regla es cambiar la direcci&oacute;n recibida por http://www.midominio.com, con una redirecci&oacute;n de tipo 301.<br /> <br /> Optamos por una redirecci&oacute;n 301, puesto que es la forma m&aacute;s eficiente de indicar a los motores de busqueda que la ruta especificada ha sido movida de forma permanente. Sin que dicha redirecci&oacute;n afecte a los rankins de nuestra p&aacute;gina, por tanto se realiza de forma transparente.<br /> <br /> Ahora para lograr redireccionar cualquier dominio a nuestro dominio principal (en este caso el .com), hacemos lo siguiente (suponiendo que tenemos registrados el .es y .net tambi&eacute;n):<br />
<pre class="code">RewriteCond %{HTTP_HOST} ^www.midominio.es$ [NC]
RewriteRule ^(.*)$ http://www.midominio.com/ [R=301,L]
RewriteCond %{HTTP_HOST} ^midominio.es$ [NC]
RewriteRule ^(.*)$ http://www.midominio.com/ [R=301,L]

RewriteCond %{HTTP_HOST} ^www.midominio.net$ [NC]
RewriteRule ^(.*)$ http://www.midominio.com/ [R=301,L]
RewriteCond %{HTTP_HOST} ^midominio.net$ [NC]
RewriteRule ^(.*)$ http://www.midominio.com/ [R=301,L]
</pre>
Siendo las 4 primeras l&iacute;neas para el dominio .es, y las &uacute;ltimas 4 para el dominio .net. Las 2 primeras de la parte del dominio.es se encargan del dominio con la triple w, y las dos siguiente del dominio sin la triple w.<br /> <br /> Finalmente si lo que queremos es redireccionar una p&aacute;gina antigua a una nueva, lo que tenemos que hacer es:<br />
<pre class="code">redirect 301 /antiguo/antiguo.html http://www.midominio.com/nuevo.html
</pre>
De esta forma cuando se intente acceder a dicha p&aacute;gina antigua se redireccionar&aacute; autom&aacute;ticamente a la nueva p&aacute;gina, y sin afectar al ranking que tuviera para los buscadores.]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=81</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/redireccionar-dominios-con-htaccess.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Migrar dominios entre servidores mediante Plesk</title>
			<link>http://www.imaginanet.com/blog/migrar-dominios-entre-servidores-mediante-plesk.html</link>
			<guid>http://www.imaginanet.com/blog/migrar-dominios-entre-servidores-mediante-plesk.html</guid>
			<comments>http://www.imaginanet.com/blog/migrar-dominios-entre-servidores-mediante-plesk.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Fri, 17 Jun 2011 09:42:11 +0100</pubDate>
					<category><![CDATA[Servidores y Seguridad]]></category>
					<description><![CDATA[En ocasiones es necesario realizar un cambio de servidor para   nuestras webs. El gran problema es que el traspaso no s&oacute;lo implica mover   los archivos de la web, si no es mucho m&aacute;s: cuentas de correo con sus   emails, bases de datos, configuraci&oacute;n DNS, configuraci&oacute;n de la quota  del  dominio,...]]></description>
			<content:encoded><![CDATA[><p>En ocasiones es necesario realizar un cambio de servidor para   nuestras webs. El gran problema es que el traspaso no s&oacute;lo implica mover   los archivos de la web, si no es mucho m&aacute;s: cuentas de correo con sus   emails, bases de datos, configuraci&oacute;n DNS, configuraci&oacute;n de la quota  del  dominio, etc.</p>
<p>Mover los archivos mediante FTP y realizar una  importaci&oacute;n de la  base de datos es posible, pero cuando se tratan de  unos cuantos miles  de dominios, bases de datos y tener que crear de  nuevo las cuentas de  correo (y perder los correos guardados en el  servidor), resulta  realmente pesado e ineficiente.</p>
<h3>Administrador de migraciones de Plesk</h3>
<p>Si nuestro servidor tiene instalado el panel de control Plesk, el  proceso se simplifica de gran manera, ya que &eacute;l har&aacute; por nosotros toda  la transferencia de archivos y configuraci&oacute;n por nosotros de los  dominios entre los hosts que deseemos.</p>
<p>En primer lugar, pulsaremos sobre el bot&oacute;n "<strong>Administrador de migraciones</strong>" de la pantalla de inicio</p>
<p>&nbsp;</p>
<p><img title="Administrador de Migraciones" src="http://www.imaginanet.com/ftp/articulos_web/migraciones_plesk/1.png" alt="Administraci&oacute;n de migraciones de Plesk para transferir hosts entre servidores" width="144" height="40" /></p>
<p>&nbsp;</p>
<p>Entonces entraremos en la pantalla principal de las migraciones de Plesk, con las migraciones ya hechas, en proceso y su estado.</p>
<p>&nbsp;</p>
<p><img title="Pantalla principal de las migraciones de Plesk de nuestro servidor" src="http://www.imaginanet.com/ftp/articulos_web/migraciones_plesk/2.png" alt="Pantalla principal de migraciones de Plesk" width="593" height="302" /></p>
<p>&nbsp;</p>
<p>Pulsamos sobre "<strong>Iniciar Migraci&oacute;n nueva</strong>" para iniciar una nueva migraci&oacute;n que nos llevar&aacute; a la introducci&oacute;n de <strong>credenciales en el servidor origen</strong>: direcci&oacute;n IP y cuenta de administrador (root en servidores Linux y Administrador en servidores Windows).</p>
<p>&nbsp;</p>
<p><img title="Introducci&oacute;n de credenciales en el host origen" src="http://www.imaginanet.com/ftp/articulos_web/migraciones_plesk/31.png" alt="Credenciales en el servidor origen" width="482" height="141" /></p>
<p>&nbsp;</p>
<p>En esta pantalla es importante estar atentos&nbsp; a la parte inferior la  opci&oacute;n de transferir todos los dominios o s&oacute;lo los dominios  seleccionados.</p>
<p>&nbsp;</p>
<p><img title="Elegimos si queremos transferir todos o algunos dominios" src="http://www.imaginanet.com/ftp/articulos_web/migraciones_plesk/32.png" alt="Deberemos seleccionar si queremos transferir todos o s&oacute;lo los dominios seleccionados" width="653" height="116" /></p>
<p>&nbsp;</p>
<p>En este punto, Plesk conectar&aacute; con el servidor origen y en la opci&oacute;n  inferior podremos decidir sin transferir s&oacute;lo correo, archivos o todo.  En nuestro caso hemos seleccionado s&oacute;lo migrar algunos dominios.</p>
<p>&nbsp;</p>
<p><img title="Selecci&oacute;n de dominios" src="http://www.imaginanet.com/ftp/articulos_web/migraciones_plesk/4.png" alt="Seleccionamos los dominios a transferir" width="316" height="110" /></p>
<p>&nbsp;</p>
<p>En la &uacute;ltima pantalla de migraci&oacute;n, Plesk nos pregunta sobre qu&eacute;  hacer en caso de conflictos en la migraci&oacute;n. Por ejemplo puede ser que  si la configuraci&oacute;n del servidor s&oacute;lo permite una base de datos por  dominio y migramos un dominio que contiene dos, crear&aacute; un conflicto. La  mejor opci&oacute;n en este punto es <strong>mantener las opciones por defecto</strong>.</p>
<p>Finalmente la migraci&oacute;n se inicia y volvemos a la pantalla inicial  del asistente de migraciones, donde podemos ver una barra de progreso en  la migraci&oacute;n que acabamos de realizar. En funci&oacute;n de la velocidad y  peso de los archivos a transferir durar&aacute; m&aacute;s o menos.</p>
<p>Tras terminar, es posible que la migraci&oacute;n se haya completado con advertencias, aunque por lo general <em>no suelen ser importantes</em>.  Podemos ver el informe final de la migraci&oacute;n y liberar el espacio  ocupado por ella en el disco duro del servidor destino clickando sobre  ella.</p>
<p>&nbsp;</p>
<p><img title="Informe final de la migraci&oacute;n" src="http://www.imaginanet.com/ftp/articulos_web/migraciones_plesk/5.png" alt="Informe final de la migraci&oacute;n de Plesk" width="546" height="166" /></p>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=80</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/migrar-dominios-entre-servidores-mediante-plesk.html</feedburner:origLink>
		</item>
				
		<item>
			<title>El patrón singleton con PHP</title>
			<link>http://www.imaginanet.com/blog/el-patron-singleton-con-php.html</link>
			<guid>http://www.imaginanet.com/blog/el-patron-singleton-con-php.html</guid>
			<comments>http://www.imaginanet.com/blog/el-patron-singleton-con-php.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Tue, 31 May 2011 21:08:30 +0100</pubDate>
					<category><![CDATA[PHP]]></category>
					<description><![CDATA[Algunas veces nos interesa tener controlada la creaci&oacute;n de objetos por  motivos como por ejemplo el ahorro de memoria. Una forma de hacer esto  es utilizando el patr&oacute;n de dise&ntilde;o "Singleton". Vamos a estudiar un  ejemplo en PHP para ver su utilidad, funcionamiento e implementaci&oacute;n.
Un claro ejemplo de la...]]></description>
			<content:encoded><![CDATA[><p>Algunas veces nos interesa tener controlada la creaci&oacute;n de objetos por  motivos como por ejemplo el ahorro de memoria. Una forma de hacer esto  es utilizando el patr&oacute;n de dise&ntilde;o "Singleton". Vamos a estudiar un  ejemplo en PHP para ver su utilidad, funcionamiento e implementaci&oacute;n.</p>
<p>Un claro ejemplo de la utilidad de este patr&oacute;n ser&iacute;a una clase para trabajar con bases de datos. Si cada vez que necesitemos conectarnos tenemos que crear una instancia del objeto, estar&iacute;amos aumentando el consumo de memoria de nuestra aplicaci&oacute;n de una manera innecesaria. Lo que normalmente suele hacer la gente es utilizar una variable global que ser&iacute;a una instancia de ese objecto, pero el uso de variables globales no es recomendado por multitud de razones que dar&iacute;an para otro "Post".</p>
<p>Para conseguir nuestro objetivo lo primero que tenemos que hacer es no permitir crear instancias del objeto, para esto basta con "ocultar" el constructor declar&aacute;ndolo como "private". Lo siguiente que necesitamos es crear un m&eacute;todo est&aacute;tico que nos devuelva una instancia de ese objeto, si existe una ya creada la devolvemos y si no creamos una nueva.</p>
<p>Veamos un ejemplo de implementaci&oacute;n:</p>
<pre class="code php">
	class Database {
		static private $instance = null;
		
		private function __contruct() {}
		
		public static function getInstance() {
			if (self::$instance == null) {
				self::$instance = new Database();
			}
			return self::$instance;
		}
		
		public function connect($dsn) {
			...
		}
		
		public function query($sql) {
			...
		}
		
		public function executeQuery() {
			...
		}
		
		public function getResult() {
			...
		}
		
		public function disconnect() {
			...
		}
	}
</pre>
<br /><br />
<p>Éste sería un prototipo de una clase para trabajar con una base de datos. Como podemos ver, ya no podremos hacer "$db = new Database();", por lo que nos aseguramos el ahorro de memoria. En su lugar para obtener el objeto que deseamos tendremos que hacer:</p>
<pre class="code php">
	...
	$db = Database::getInstance();
	$db->connect($dsn);
	...
	...
</pre>
<br /><br />
<p>Siempre que llamemos al método estático "getInstance()" se comprobará que no exista ya una instancia de este objeto, si no existe crearemos una, la guardaremos como una propiedad estática de la clase y la devolveremos, muy simple.</p>
<p>Otra forma de ejecutar el código anterior sin tener que inicializar ninguna variable:</p>
<pre class="code php">
	...
	Database::getInstance()->connect($dsn);
	...
</pre>
<br /><br />
<p>Como se puede apreciar, utilizando este patrón adecuadamente, a parte de ahorrar memoria, tendríamos un código más limpio y libre de variables globales, que pueden ser modificadas por accidente en otros procesos</p>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=79</wfw:commentRss>
			<slash:comments>2</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/el-patron-singleton-con-php.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Crear un pasador con jQuery</title>
			<link>http://www.imaginanet.com/blog/crear-un-pasador-con-jquery.html</link>
			<guid>http://www.imaginanet.com/blog/crear-un-pasador-con-jquery.html</guid>
			<comments>http://www.imaginanet.com/blog/crear-un-pasador-con-jquery.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Mon, 23 May 2011 10:46:36 +0100</pubDate>
					<category><![CDATA[XHTML]]></category>
					<category><![CDATA[JavaScript]]></category>
					<category><![CDATA[CSS]]></category>
					<category><![CDATA[jQuery]]></category>
					<description><![CDATA[Vamos a ver como crear un pasador sencillo con jQuery. Para ello lo primero es crear la estructura html, donde tendremos b&aacute;sicamente una capa contenido con un ancho fijo y overflow oculto, y dentro de esta una capa llamada carril que contiene todos los elementos del pasador, y ser&aacute; la que iremos moviendo de...]]></description>
			<content:encoded><![CDATA[>Vamos a ver como crear un pasador sencillo con jQuery. Para ello lo primero es crear la estructura html, donde tendremos b&aacute;sicamente una capa contenido con un ancho fijo y overflow oculto, y dentro de esta una capa llamada carril que contiene todos los elementos del pasador, y ser&aacute; la que iremos moviendo de posici&oacute;n para as&iacute; conseguir el efecto buscado.<br />
<pre class="code">    <div class="marco">
       <div class="contenido">
           <div class="carril">
               <div class="mini">
                   <a class="enlace" href="#"><img src="/imaginanet/imgx/obra1.jpg" alt="" /></a>
               </div>
               <div class="mini">
                   <a class="enlace" href="#"><img src="/imaginanet/imgx/obra2.jpg" alt="" /></a>
               </div>
               <div class="mini">
                   <a class="enlace" href="#"><img src="/imaginanet/imgx/obra3.jpg" alt="" /></a>
               </div>                
           </div>
       </div>
       <a class="prev nomore" href="#"></a>
       <a class="next" href="#"></a>
   </div>
</pre>
Los enlaces para pasar de p&aacute;gina los colocamos en una capa padre a la capa contenido, dado que la capa contenido tiene overflow oculto y de meterlos dentro no se ver&iacute;an. Por tanto tendremos el siguiente c&oacute;digo css:<br />
<pre class="code">div.marco div.contenido {
   width: 172px;
   height: 80px;
   overflow: hidden;
   margin-left: 20px;
}
div.marco div.contenido div.carril {
   position: relative;
   white-space: nowrap;
}
div.marco div.contenido div.carril div.mini {
   display: inline-block;
   _display: inline;
   #display: inline;
   width: 80px;
   height: 80px;
   overflow:hidden;    
}
</pre>
A descatar que los elementos que van dentro del carril, los colocamos con inline-block, y la capa padre (carril) va con white-space: nowrap para que estos elementos del pasador no salten de l&iacute;nea.<br /> <br /> Ahora solo queda crear el c&oacute;digo javascript que mueva el pasador, para ello necesitamos saber cuanto tama&ntilde;o debemos desplazar el carril para hacer el cambio de p&aacute;gina y simular el pasador. Este tama&ntilde;o lo calculamos sabiendo la distancia que separa un elemento del carril (un div.mini) de otro, m&aacute;s su ancho, y multiplicamos el resultado por el n&uacute;mero de items que tenemos por p&aacute;gina.<br />
<pre class="code">       if (nitems &lt;= itemsxpag) {
           $(this).find("a.next").remove();
           $(this).find("a.prev").remove();
       }
       else {
           $(this).parent().find("a.next").click(function (e) {
               e.preventDefault();

               if (pagactual == npages)
                   return;
               $(self).parent().find("a.prev").removeClass("nomore");
               
               ul.animate({left:"-=" + ancho + "px"});
               pagactual++;
               
               if (pagactual == npages)
                   $(this).addClass("nomore");
           });
           $(this).parent().find("a.prev").click(function (e) {
               e.preventDefault();

               if (pagactual == 1)
                   return;
               $(self).parent().find("a.next").removeClass("nomore");
               
               ul.animate({left:"+=" + ancho + "px"});
               pagactual--;
               if (pagactual == 1)
                   $(this).addClass("nomore");
           });
       }
</pre>
En este c&oacute;digo creamos los manejadores para los clicks de los enlaces de siguiente y atras, donde b&aacute;sicamente comprobamos en que p&aacute;gina nos encontramos y si hay m&aacute;s p&aacute;ginas en la direcci&oacute;n en la que nos piden desplazarnos. La animaci&oacute;n se hace con animate de jQuery, y como podemos ver modificamos la posici&oacute;n (con left) de la capa carril, sumandole el ancho en caso de ir a una p&aacute;gina siguiente, o restandole el ancho en caso de ir a una p&aacute;gina anterior.<br /> <br /> Se puede ver el pasador explicado en funcionamiento <a href="http://www.imaginanet.com/ftp/blog/pasador/index.htm" target="_blank">aqu&iacute;</a>.]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=78</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/crear-un-pasador-con-jquery.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Validar email con javascript</title>
			<link>http://www.imaginanet.com/blog/validar-email-con-javascript.html</link>
			<guid>http://www.imaginanet.com/blog/validar-email-con-javascript.html</guid>
			<comments>http://www.imaginanet.com/blog/validar-email-con-javascript.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Fri, 20 May 2011 15:10:09 +0100</pubDate>
					<category><![CDATA[JavaScript]]></category>
					<description><![CDATA[En toda web con formularios de registro se suele incluir un campo para que el usuario introduzca su e-mail, pero antes de almacenarlo debemos asegurarnos de que el usuario nos esta facilitando un e-mail correcto, para ello podemos utilizar una expresi&oacute;n regular que compruebe que se cumplen los requisitos necesarios como...]]></description>
			<content:encoded><![CDATA[>En toda web con formularios de registro se suele incluir un campo para que el usuario introduzca su e-mail, pero antes de almacenarlo debemos asegurarnos de que el usuario nos esta facilitando un e-mail correcto, para ello podemos utilizar una expresi&oacute;n regular que compruebe que se cumplen los requisitos necesarios como tener una arroba, una extensi&oacute;n, etc.<br /> <br /> A continuaci&oacute;n la funci&oacute;n javascript que valida un email:<br />
<pre class="code">    function validarEmail(valor) {                    
       if (/(?:[a-z0-9!#$%&amp;'*+/=?^_`{|}~-]+(?:.[a-z0-9!#$%&amp;'*+/=?^_`{|}~-]+)*|"(?:[x01-x08x0bx0cx0e-x1fx21x23-x5bx5d-x7f]|[x01-x09x0bx0cx0e-x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[x01-x08x0bx0cx0e-x1fx21-x5ax53-x7f]|[x01-x09x0bx0cx0e-x7f])+)])/.test(valor)){
           return (true)
       } else {
           return (false);
       }
   }
</pre>
Para utilizarla solo hay que pasarle el email a verificar y nos devolver&aacute; un booleano verdadero si es valido o falso en caso contrario.]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=77</wfw:commentRss>
			<slash:comments>1</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/validar-email-con-javascript.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Validar nif/dni con javascript</title>
			<link>http://www.imaginanet.com/blog/validar-nifdni-con-javascript.html</link>
			<guid>http://www.imaginanet.com/blog/validar-nifdni-con-javascript.html</guid>
			<comments>http://www.imaginanet.com/blog/validar-nifdni-con-javascript.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Fri, 20 May 2011 14:52:43 +0100</pubDate>
					<category><![CDATA[Comercio electrónico]]></category>
					<category><![CDATA[JavaScript]]></category>
					<description><![CDATA[Lo primero es saber en que consiste el algoritmo de validaci&oacute;n de un nif/dni. Y es tan simple como coger los 8 n&uacute;meros del documento y hacer el modulo 23 de dicho n&uacute;mero. Este 23 es porque existen 23 letras para el nif/dni:  TRWAGMYFPDXBNJZSQVHLCKE  Vamos a calcular la letra de un nif/dni ficticio: 12345678...]]></description>
			<content:encoded><![CDATA[>Lo primero es saber en que consiste el algoritmo de validaci&oacute;n de un nif/dni. Y es tan simple como coger los 8 n&uacute;meros del documento y hacer el modulo 23 de dicho n&uacute;mero. Este 23 es porque existen 23 letras para el nif/dni:<br /> <br /> <em>TRWAGMYFPDXBNJZSQVHLCKE</em><br /> <br /> Vamos a calcular la letra de un nif/dni ficticio:<br /> <em>12345678</em><br /> <br /> Calculamos el modulo 23 del n&uacute;mero anterior y obtenemos: 14, por tanto este nif/dni tiene letra Z, dado que empezamos a contar las letras de izquierda a derecha y comenzando por el valor 0, por tanto es como buscar la letra 15 (si empiezas contando por el 1).<br /> <br /> Este algoritmo en javascript en una funci&oacute;n quedar&iacute;a as&iacute;:<br />
<pre class="code">function letraDni(numeros) {
    var letras = "TRWAGMYFPDXBNJZSQVHLCKE";
    return letras.charAt(numeros % 23);
}
</pre>
Ahora tan solo quedar&iacute;a llamarla con los 8 n&uacute;meros del nif/dni que queremos comprobar, y comparar la letra que nos retorna la funci&oacute;n con la letra indicada por el usuario.]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=76</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/validar-nifdni-con-javascript.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Validar número de cuenta bancaria</title>
			<link>http://www.imaginanet.com/blog/validar-numero-de-cuenta-bancaria.html</link>
			<guid>http://www.imaginanet.com/blog/validar-numero-de-cuenta-bancaria.html</guid>
			<comments>http://www.imaginanet.com/blog/validar-numero-de-cuenta-bancaria.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Fri, 20 May 2011 14:07:55 +0100</pubDate>
					<category><![CDATA[Comercio electrónico]]></category>
					<category><![CDATA[JavaScript]]></category>
					<description><![CDATA[Es muy com&uacute;n querer validar un numero de cuenta bancaria para evitar errores de transcripci&oacute;n. Si nos fijamos un n&uacute;mero de cuenta esta formado por 20 d&iacute;gitos, separados en 4 bloques:  1234-1234-12-1234567890  Los 4 primeros d&iacute;gitos corresponden al banco, los siguientes 4 a la sucursal, los 2...]]></description>
			<content:encoded><![CDATA[>Es muy com&uacute;n querer validar un numero de cuenta bancaria para evitar errores de transcripci&oacute;n. Si nos fijamos un n&uacute;mero de cuenta esta formado por 20 d&iacute;gitos, separados en 4 bloques:<br /> <br /> <em>1234-1234-12-1234567890</em><br /> <br /> Los 4 primeros d&iacute;gitos corresponden al banco, los siguientes 4 a la sucursal, los 2 siguientes son los d&iacute;gitos de control, y los &uacute;ltimos 10 son el n&uacute;mero de cuenta dentro de la sucursal.<br /> <br /> Para validar la cuenta se utilizan los dos d&iacute;gitos de control, siendo el primero necesario para validar los 8 primeros (banco y sucursal), y el segundo para validar los &uacute;ltimos 10 (del n&uacute;mero de cuenta).<br /> <br /> A continuaci&oacute;n vamos a calcular los d&iacute;gitos de control para la cuenta ficticia que hemos puesto antes, de esta forma comprobaremos si los d&iacute;gitos de control de arriba son erroneos:<br /> <em>banco:</em> 1234<br /> <em>sucursal:</em> 1234<br /> <em>cuenta:</em> 1234567890<br /> <br /> Antes de comenzar necesitamos saber la siguiente lista de pesos:<br /> <em>1, 2, 4, 8, 5, 10, 9, 7, 3, 6</em><br /> <br /> <em>Empezamos con el primer d&iacute;gito de control:</em><br /> Cogemos los 4 d&iacute;gitos del banco y sucursal, 12341234 y como tenemos 10 pesos (listados antes), a&ntilde;adimos dos ceros delante 0012341234, y multiplicamos cada d&iacute;gito por su peso correspondiente, el orden vienen dado por la posici&oacute;n que ocupan, es decir, el primer n&uacute;mero por el primero peso, el segundo n&uacute;mero por el segundo peso... cada resultado lo sumamos para obtener un solo n&uacute;mero.<br /> (0 * 1) + (0 * 2) + (1 * 4) + (2 * 8) + (3 * 5) + (4 * 10) + (1 * 9) + (2 * 7) + (3 * 3) + (4 * 6) = 4 + 16 + 15 + 40 + 9 + 14 + 9 + 24 = 131<br /> <br /> Ahora hacemos la siguiente operaci&oacute;n para obtener el primer n&uacute;mero del d&iacute;gito de control:<br /> 11 - (131 mod 11) = 11 - 10 = 1<br /> <br /> Y para <em>obtener el segundo d&iacute;gito de control</em> operamos de la misma forma multiplicando los 10 d&iacute;gitos de la cuenta por su peso correspondiente, sumando estos resultados, y haciendo la resta con el modulo de 11:<br /> (1 * 1) + (2 * 2) + (3 * 4) + (4 * 8) + (5* 5) + (6 * 10) + (7 * 9) + (8 * 7) + (9 * 3) + (0 * 6) = 1 + 4 + 12 + 32 + 25 + 60 + 63 + 56 + 27 + 0 = 280<br /> <br /> 11 - (280 mod 11) = 11 - 5 = 6<br /> <br /> Por tanto los d&iacute;gitos de control son el valor 16, y no 12 como hab&iacute;amos puesto al principio. Suele ser t&iacute;pico que necesitemos validar esto en javascript en un formulario, por ello a continuaci&oacute;n un ejemplo de funci&oacute;n que lo har&iacute;a:<br />
<pre class="code">function calculaDigito(valores) {
     pesos = new Array(1, 2, 4, 8, 5, 10, 9, 7, 3, 6);
     d = 0;
     for (i=0; i&lt;=9; i++) {
       d += parseInt(valores.charAt(i)) * pesos[i];
     }
     d = 11 - (d % 11);
     if (d==11) d=0;
     if (d==10) d=1;
     return d;
}
</pre>
A esta funci&oacute;n habr&iacute;a que llamarla dos veces, primero con los 8 primeros numeros (banco y sucursal) mas dos ceros delante, y luego con los 10 n&uacute;meros de la cuenta, y ya tendr&iacute;amos los d&iacute;gitos de control.]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=75</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/validar-numero-de-cuenta-bancaria.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Comandos útiles para un servidor Ubuntu / Debian</title>
			<link>http://www.imaginanet.com/blog/comandos-utiles-para-un-servidor-ubuntu-debian.html</link>
			<guid>http://www.imaginanet.com/blog/comandos-utiles-para-un-servidor-ubuntu-debian.html</guid>
			<comments>http://www.imaginanet.com/blog/comandos-utiles-para-un-servidor-ubuntu-debian.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Tue, 17 May 2011 14:29:22 +0100</pubDate>
					<category><![CDATA[Servidores y Seguridad]]></category>
					<category><![CDATA[Linux]]></category>
					<description><![CDATA[Completamos el listado de comandos &uacute;tiles para servidores web Linux con algunos comandos propios para distribuciones Ubuntu / Debian:
Firewall:
Poner en marcha el firewall
ufw enable
Parar firewall
ufw disable
Estado
ufw status
Bloquear puerto:
ufw deny port
Bloquear tr&aacute;fico procedente de cierta IP:
ufw deny from...]]></description>
			<content:encoded><![CDATA[><p>Completamos el listado de <a title="Comandos &uacute;tiles para servidores web LAMP" href="http://www.imaginanet.com/blog/comandos-utiles-para-un-servidor-linux.html">comandos &uacute;tiles para servidores web Linux</a> con algunos comandos propios para distribuciones Ubuntu / Debian:</p>
<h3>Firewall:</h3>
<p>Poner en marcha el firewall</p>
<pre class="code">ufw enable</pre>
<p>Parar firewall</p>
<pre class="code">ufw disable</pre>
<p>Estado</p>
<pre class="code">ufw status</pre>
<p>Bloquear puerto:</p>
<pre class="code">ufw deny port</pre>
<p>Bloquear tr&aacute;fico procedente de cierta IP:</p>
<pre class="code">ufw deny from ip</pre>
<p>Permitir puerto:</p>
<pre class="code">ufw allow port</pre>
<p>&nbsp;</p>
<h3>Manejo de paquetes:</h3>
<p>Actualizar lista de paquetes disponibles</p>
<pre class="code">apt-get update</pre>
<p>Actualizar todos los paquetes (hacer con cuidado en un servidor en producci&oacute;n):</p>
<pre class="code">apt-get upgrade</pre>
<p>Actualizar a la siguiente versi&oacute;n de la distribuci&oacute;n (hacer con cuidado en un servidor en producci&oacute;n):</p>
<pre class="code">apt-get dist-upgrade</pre>
<p>Buscar un paquete disponible:</p>
<pre class="code">apt-cache search paquete</pre>
<p>Instalar un paquete:</p>
<pre class="code">apt-get install paquete</pre>
<p>Eliminar un paquete:</p>
<pre class="code">apt-get remove paquete</pre>
<p>Intentar solucionar conflictos y dependencias rotas:</p>
<pre class="code">dpkg &ndash;configure -a</pre>
<h3>Art&iacute;culos relacionados</h3>
<ul>
<li><a href="http://www.imaginanet.com/blog/comandos-utiles-para-un-servidor-linux.html">Comandos &uacute;tiles para servidores web Linux&nbsp;</a></li>
<li><a title="Comandos &uacute;tiles para un servidor web RedHat / CentOS" href="http://www.imaginanet.com/blog/comandos-utiles-para-un-servidor-redhat-centos.html">Comandos &uacute;tiles para servidores web RedHat / CentOS</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=74</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/comandos-utiles-para-un-servidor-ubuntu-debian.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Comandos útiles para un servidor RedHat / CentOS</title>
			<link>http://www.imaginanet.com/blog/comandos-utiles-para-un-servidor-redhat-centos.html</link>
			<guid>http://www.imaginanet.com/blog/comandos-utiles-para-un-servidor-redhat-centos.html</guid>
			<comments>http://www.imaginanet.com/blog/comandos-utiles-para-un-servidor-redhat-centos.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Tue, 17 May 2011 13:40:43 +0100</pubDate>
					<category><![CDATA[Servidores y Seguridad]]></category>
					<category><![CDATA[Linux]]></category>
					<description><![CDATA[Completamos el listado de comandos &uacute;tiles para servidores web Linux con algunos comandos propios para distribuciones RedHat / CentOS:
Manejo de paquetes:
Buscar paquetes
yum list paquete
Instalar paquete
yum install paquete
Actualizar paquete
yum update paquete
Borrar paquete
yum remove paquete
Servicios
Asociar un servicio...]]></description>
			<content:encoded><![CDATA[><p>Completamos el listado de <a title="Comandos &uacute;tiles para servidores web Linux" href="http://www.imaginanet.com/blog/comandos-utiles-para-un-servidor-linux.html">comandos &uacute;tiles para servidores web Linux</a> con algunos comandos propios para distribuciones RedHat / CentOS:</p>
<h3>Manejo de paquetes:</h3>
<p>Buscar paquetes</p>
<pre class="code">yum list paquete</pre>
<p>Instalar paquete</p>
<pre class="code">yum install paquete</pre>
<p>Actualizar paquete</p>
<pre class="code">yum update paquete</pre>
<p>Borrar paquete</p>
<pre class="code">yum remove paquete</pre>
<h3>Servicios</h3>
<p>Asociar un servicio al inicio</p>
<pre class="code">chkconfig vsftpd on</pre>
<h3>Art&iacute;culos relacionados</h3>
<ul>
<li><a title="Comandos &uacute;tiles para un servidor web LAMP" href="http://www.imaginanet.com/blog/comandos-utiles-para-un-servidor-linux.html">Comandos &uacute;tiles para servidores web Linux</a></li>
<li><a title="Comandos &uacute;tiles para un servidor web Ubuntu / Debian" href="http://www.imaginanet.com/blog/comandos-utiles-para-un-servidor-ubuntu-debian.html">Comandos &uacute;tiles para servidores web Ubuntu / Debian</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=73</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/comandos-utiles-para-un-servidor-redhat-centos.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Comandos útiles para un servidor Linux</title>
			<link>http://www.imaginanet.com/blog/comandos-utiles-para-un-servidor-linux.html</link>
			<guid>http://www.imaginanet.com/blog/comandos-utiles-para-un-servidor-linux.html</guid>
			<comments>http://www.imaginanet.com/blog/comandos-utiles-para-un-servidor-linux.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Tue, 17 May 2011 12:18:26 +0100</pubDate>
					<category><![CDATA[Servidores y Seguridad]]></category>
					<category><![CDATA[Linux]]></category>
					<description><![CDATA[Para la programaci&oacute;n de p&aacute;ginas web, si contratamos un servidor web dedicado o VPS LAMP (Linux Apache MySQL PHP) y necesitamos realizar algunos ajustes en el sistema via SSH, necesitaremos tener nociones del sistema que vamos a tratar.
A continuaci&oacute;n listamos una serie de comandos &uacute;tiles para...]]></description>
			<content:encoded><![CDATA[><div>
<p>Para la <a title="Programaci&oacute;n de p&aacute;ginas web" href="http://www.imaginanet.com/programacion-web.html">programaci&oacute;n de p&aacute;ginas web</a>, si contratamos un <strong>servidor web</strong> dedicado o VPS LAMP (<em>Linux Apache MySQL PHP</em>) y necesitamos realizar algunos ajustes en el sistema via SSH, necesitaremos tener nociones del sistema que vamos a tratar.</p>
<p>A continuaci&oacute;n listamos una serie de comandos &uacute;tiles para servidores Linux y al final dejamos indicados los comandos propios para distribuciones Ubuntu / Debian y RedHat / CentOS.</p>
</div>
<p><span style="font-size: 12px; font-weight: bold;"><br />Comandos generales:</span></p>
<p>Conectar a trav&eacute;s de SSH</p>
<pre class="code">ssh root@direccionip</pre>
<p>Ejecutar un comando con privilegios de root (si no lo somos)</p>
<pre class="code">sudo comando</pre>
<p>Obtener versi&oacute;n del kernel</p>
<pre class="code">uname -a</pre>
<p>Espacio en disco ocupado por un archivo o carpeta</p>
<pre class="code">du -hlsc carpeta_o_archivo</pre>
<p>Espacio libre en los sistemas de ficheros</p>
<pre class="code"> df &nbsp; </pre>
<p>Empaquetar</p>
<pre class="code">tar cvf paquete.tar directorio_a_empaquetar</pre>
<p>Desempaquetar</p>
<pre class="code">tar xvf paquete.tar</pre>
<p>&nbsp;</p>
<h3>Servicios:</h3>
<p>Iniciar un servicio</p>
<pre class="code">/etc/init.d/service start</pre>
<p>Parar un servicio</p>
<pre class="code">/etc/init.d/service stop</pre>
<p>Estado de un servicio</p>
<pre class="code">/etc/init.d/service status</pre>
<p>Reiniciar servicio</p>
<pre class="code">/etc/init.d/service restart</pre>
<p>&nbsp;</p>
<h3>Interfaces de red:</h3>
<p>Informaci&oacute;n de las interfaces</p>
<pre class="code">ifconfig</pre>
<p>Parar una interfaz</p>
<pre class="code">ifdown interfaz</pre>
<p>Levantar una interfaz</p>
<pre class="code">ifup interfaz</pre>
<p>Editar archivo de configuraci&oacute;n de las interfaces</p>
<pre class="code">nano /etc/network/interfaces</pre>
<p>Editar archivo de servidores de nombres</p>
<pre class="code">nano /etc/resolv.conf</pre>
<p>Editar archivo hosts</p>
<pre class="code">nano /etc/hosts</pre>
<p>&nbsp;</p>
<h3>MySQL</h3>
<p>Exportar base de datos</p>
<pre class="code">mysqldump --user USUARIO --password=CONTRASE&Ntilde;A nombre_base_datos &gt; archivo.sql</pre>
<p>Exportar base de datos</p>
<pre class="code">mysqldump -u USUARIO -p nombre_base_datos &gt; archivo.sql</pre>
<p>Importar base de datos&nbsp;(debe existir antes esa base de datos)</p>
<pre class="code">mysql -u USUARIO -p nombre_base_datos &lt; archivo.sql</pre>
<p>&nbsp;</p>
<h3>Art&iacute;culos relacionados</h3>
<ul>
<li><a title="Comandos para un servidor LAMP (Linux Apache MySQL PHP) en Ubuntu / Debian" href="http://www.imaginanet.com/blog/comandos-utiles-para-un-servidor-ubuntu-debian.html">Comandos &uacute;tiles para un servidor web Ubuntu / Debian</a></li>
<li><a title="Comandos &uacute;tiles para un servidor web CentOS / RedHat" href="http://www.imaginanet.com/blog/comandos-utiles-para-un-servidor-redhat-centos.html">Comandos &uacute;tiles para un servidor web CentOS / RedHat</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=72</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/comandos-utiles-para-un-servidor-linux.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Obtener datos del muro de Facebook con PHP</title>
			<link>http://www.imaginanet.com/blog/obtener-datos-del-muro-de-facebook-con-php.html</link>
			<guid>http://www.imaginanet.com/blog/obtener-datos-del-muro-de-facebook-con-php.html</guid>
			<comments>http://www.imaginanet.com/blog/obtener-datos-del-muro-de-facebook-con-php.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Fri, 13 May 2011 12:28:52 +0100</pubDate>
					<category><![CDATA[Redes Sociales]]></category>
					<category><![CDATA[XHTML]]></category>
					<category><![CDATA[PHP]]></category>
					<description><![CDATA[Podemos obtener f&aacute;cilmente datos del muro de facebook con PHP gracias al "graph api". Lo &uacute;nico que tenemos que hacer es hacer una llamada al API y procesar los datos que nos devuelve en formato JSON. PHP nos ofrece herramientas para hacer esto de la forma m&aacute;s sencilla posible
Vamos a ver un ejemplo de como...]]></description>
			<content:encoded><![CDATA[><p>Podemos obtener f&aacute;cilmente datos del muro de facebook con PHP gracias al "graph api". Lo &uacute;nico que tenemos que hacer es hacer una llamada al API y procesar los datos que nos devuelve en formato JSON. PHP nos ofrece herramientas para hacer esto de la forma m&aacute;s sencilla posible</p>
<p>Vamos a ver un ejemplo de como obtener los datos del muro de <a href="http://www.imaginanet.com">Imaginanet</a>. Para ello debemos saber el identificador de la p&aacute;gina (o del usuario en caso de que el muro que nos interese sea el de una persona y no una p&aacute;gina). Ese identificador lo obtenemos, por ejemplo de la url de la p&aacute;gina. Si accedemos a la p&aacute;gina de facebook de <a href="http://www.imaginanet.com">Imaginanet</a>, la url que tenemos es la siguiente: <a href="http://www.facebook.com/pages/Imaginanet/293803966478">http://www.facebook.com/pages/Imaginanet/293803966478</a>. El n&uacute;mero que aparece al final es el identificador que queremos.</p>
<br />
<pre class="code php">	$id_usuario = "293803966478";
	$respuesta = file_get_contents("https://graph.facebook.com/" . $id_usuario . "/feed");

</pre>
<br />
<p>En la variable "$respuesta" tenemos los datos que queremos en formato JSON, para transformarlos en un array asociativo que nos permita manejarlo de forma sencilla solo tenemos que hacer lo siguiente:</p>
<br />
<pre class="code php">	$datos = json_decode($respuesta,true);

</pre>
<br />
<p>Ahora en la variable "$datos" tenemos un array asociativo con los datos del muro.</p>
<p>Si por ejemplo quisieramos sacar las &uacute;ltimas 4 fotos que haya en las publicaciones del muro, har&iacute;amos lo siguiente:</p>
<br />
<pre class="code php">	$facebook = array();
	$i = 0;
	foreach ($datos["data"] as $value) {
		if (trim($value["picture"]) != "") {
			$facebook[$i]["src"] = trim($value["picture"]);
			$facebook[$i]["titulo"] = trim($value["name"]);
			$facebook[$i]["texto"] = trim($value["description"]);
			$i++;
		}
		if ($i&gt;4) break;
	}
	$html = "";
	foreach ($facebook as $key =&gt; $value) {
		$html .= '
			<div>
				<h1>'.$value["titulo"].'</h1>
				&lt;img src="' . $value["src"] . '" alt="' . $value["titulo"] . '" /&gt;
				<div>'.$value["texto"].'</div>
			</div>
		';
	}

	echo $html;

</pre>
<br />
<p>Hay que tener en cuenta que esto s&oacute;lo funcionar&iacute;a para muros p&uacute;blicos, de otra forma tendr&iacute;amos que utilizar alg&uacute;n m&eacute;todo de autenticaci&oacute;n. Podemos utilizar alguna de las clases PHP que nos provee facebook, para trabajar con esta API.</p>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=71</wfw:commentRss>
			<slash:comments>8</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/obtener-datos-del-muro-de-facebook-con-php.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Comprimir archivos dinámicamente en ZIP con PHP</title>
			<link>http://www.imaginanet.com/blog/comprimir-archivos-dinamicamente-en-zip-con-php.html</link>
			<guid>http://www.imaginanet.com/blog/comprimir-archivos-dinamicamente-en-zip-con-php.html</guid>
			<comments>http://www.imaginanet.com/blog/comprimir-archivos-dinamicamente-en-zip-con-php.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Fri, 29 Apr 2011 10:08:07 +0100</pubDate>
					<category><![CDATA[PHP]]></category>
					<description><![CDATA[En ocasiones es necesario comprimir din&aacute;micamente uno o varios archivos para generar un &uacute;nico archivo que un usuario se pueda descargar en funci&oacute;n de los par&aacute;metros de entrada. Algunos ejemplos en los que se puede usar:                 

Informes de algunos meses del a&ntilde;o.
M&uacute;ltiples...]]></description>
			<content:encoded><![CDATA[>En ocasiones es necesario comprimir din&aacute;micamente uno o varios archivos para generar un &uacute;nico archivo que un usuario se pueda descargar en funci&oacute;n de los par&aacute;metros de entrada. Algunos ejemplos en los que se puede usar:                 
<ul>
<li>Informes de algunos meses del a&ntilde;o.</li>
<li>M&uacute;ltiples im&aacute;genes o v&iacute;deos.</li>
<li>PDFs asociados a una p&aacute;gina.</li>
<li>Etc.</li>
</ul>
<p><strong>Con PHP podemos comprimir en formato ZIP</strong> de varias maneras, pero vamos a destacar dos:</p>
<ul>
<li>Nativamente con PHP, mediante su librer&iacute;a ZipArchive</li>
<li>Con librer&iacute;as externas, como PclZip</li>
</ul>
<h2>Comprimiendo archivos en ZIP con PHP mediante ZipArchive</h2>
<p>Si tu servidor tiene una versi&oacute;n superior a 5.2.0 y la extensi&oacute;n zlib podemos hacer uso de ella.</p>
<p>Para saber si tenemos los requisitos, debemos usar la funci&oacute;n phpinfo() en un archivo PHP y nos mostrar&aacute; toda la informaci&oacute;n relativa al servidor.</p>
<p>Por ejemplo:</p>
<pre class="code php">&lt;?php

phpinfo();

?&gt;</pre>
<br />y debemos obtener una salida parecida a la siguiente: <br /><br /><span style="text-decoration: underline;">Versi&oacute;n de PHP</span><br /><br /><br /><img title="Versi&oacute;n de PHP para comprimir archivos en formato ZIP mediante PHP" src="http://www.imaginanet.com/ftp/articulos_web/comprimir_archivos_php/phpinfo_php5210.png" alt="Captura de pantalla de la versi&oacute;n de PHP para comprimir archivos en formato ZIP mediante PHP" width="602" height="76" /><br /><br /><span style="text-decoration: underline;">ZLib activado</span><br /><img title="zlib activado para comprimir archivos en ZIP din&aacute;micamente con PHP" src="http://www.imaginanet.com/ftp/articulos_web/comprimir_archivos_php/zlib_comprimir_archivos_dinamicamente_zip.png" alt="Captura de pantalla de la funci&oacute;n phpinfo para comprimir archivos en ZIP din&aacute;micamente con PHP" width="603" height="259" /><br /><br />
<p style="margin-bottom: 0cm;">A continuaci&oacute;n podemos usar la librer&iacute;a de la siguiente manera para comprimir los archivos a.txt y b.txt en el mismo archivo ZIP:</p>
<br />
<pre class="code php">&lt;?php

$zip = new ZipArchive();

$filename = 'test.zip';

if($zip-&gt;open($filename,ZIPARCHIVE::CREATE)===true) {
        $zip-&gt;addFile('a.txt');
        $zip-&gt;addFile('b.txt');
        $zip-&gt;close();
        echo 'Creado '.$filename;
}
else {
        echo 'Error creando '.$filename;
}

?&gt;
</pre>
teniendo especial cuidado en la ejecuci&oacute;n para que tenga los permisos necesarios de escritura el archivo que comprime.
<h2>Comprimiendo archivos en ZIP con PHP mediante PclZip</h2>
<p>En ocasiones no tenemos acceso a la instalaci&oacute;n y modificaci&oacute;n de paquetes y configuraci&oacute;n de nuestro servidor, por lo que una buena opci&oacute;n es el uso de la librer&iacute;a PclZip.</p>
<p>Debemos descargar la librer&iacute;a y tras ello la guardaremos en una carpeta, por ejemplo lib.</p>
<pre class="code php">&lt;?php

require('lib/pclzip.lib.php');
$zip = new PclZip('test.zip');
$zip-&gt;create('a.txt,b.txt');

?&gt;
</pre>
<br /> Al igual que en el caso anterior, para crearlo deberemos tener permisos de ejecuci&oacute;n.<br /><br />
<h3 style="margin-bottom: 0.5cm;">Enlaces relacionados</h3>
<ul>
<li><a title="Clase ZipArchive de PHP" href="http://php.net/manual/es/class.ziparchive.php" target="_blank">PHP.net: ZipArchive</a></li>
<li><a title="Clase PclZip de PHP" href="http://www.phpconcept.net/pclzip/" target="_blank">PclZip</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=70</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/comprimir-archivos-dinamicamente-en-zip-con-php.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Cómo utilizar cualquier fuente/tipografía en nuestra página web</title>
			<link>http://www.imaginanet.com/blog/como-utilizar-cualquier-fuente-tipografia-en-nuestra-pagina-web.html</link>
			<guid>http://www.imaginanet.com/blog/como-utilizar-cualquier-fuente-tipografia-en-nuestra-pagina-web.html</guid>
			<comments>http://www.imaginanet.com/blog/como-utilizar-cualquier-fuente-tipografia-en-nuestra-pagina-web.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Wed, 27 Apr 2011 18:27:47 +0100</pubDate>
					<category><![CDATA[XHTML]]></category>
					<category><![CDATA[JavaScript]]></category>
					<category><![CDATA[CSS]]></category>
					<description><![CDATA[A la hora de crear p&aacute;ginas webs a veces nos encontramos limitados por las tipograf&iacute;as o fuentes tipogr&aacute;ficas que podemos utilizar en ellas, dado que no todos los navegadores y sistemas operativos incluyen el mismo n&uacute;mero de fuentes, y las tipograf&iacute;as de los sistemas operativos no ser&aacute;n las...]]></description>
			<content:encoded><![CDATA[>A la hora de crear p&aacute;ginas webs a veces nos encontramos limitados por las tipograf&iacute;as o fuentes tipogr&aacute;ficas que podemos utilizar en ellas, dado que no todos los navegadores y sistemas operativos incluyen el mismo n&uacute;mero de fuentes, y las tipograf&iacute;as de los sistemas operativos no ser&aacute;n las mismas. Por ello si queremos aplicar cualquier fuente a nuestra p&aacute;gina podemos hacer lo siguiente:<br /> <br /> Lo primero es descargar la fuente en formato True Type, cuya extensi&oacute;n es ttf. Una vez tengamos la fuente en ttf, debemos convertirla tambi&eacute;n a formato Open Type Embebido, es decir eot, o formato Web Open Font (woff) para tener compatibilidad con Internet explorer. Para llevar a cabo dicha conversi&oacute;n existen multitud de programas y p&aacute;ginas gratuitas, tan solo debemos buscar por las palabras &ldquo;ttf to eot&rdquo; o &ldquo;ttf to woff&rdquo; en cualquier buscador para encontrar una.<br /> <br /> Una vez tengamos la fuente en ambos formatos debemos utilizar en CSS la directiva @font-face para declarar nuestra nueva fuente, por ejemplo si hemos descargado la fuente &ldquo;futurastd-light-webfont.ttf&rdquo;, debemos colocar el siguiente c&oacute;digo en nuestra hoja de estilos:<br />
<pre class="code">	@font-face {
		font-family: "Futura";
		font-style: normal;
		font-weight: normal;
		src: local("?"), url("/fonts/futurastd-light-webfont.woff") format("woff"), url("/fonts/futurastd-light-webfont.ttf") format("truetype");
	}
</pre>
<br /> Siendo font-family el nombre que utilizaremos en el resto de la hoja de estilos para referenciar a nuestra nueva fuente.<br /> <br /> A continuaci&oacute;n un ejemplo de como utilizar nuestra nueva fuente que hemos declarado arriba:<br />
<pre class="code">	p {
		font-family: Futura;
	}
</pre>
<br /> De esta forma todas las etiquetas &ldquo;p&rdquo; tendr&aacute;n como estilo nuestra nueva fuente declarada como Futura.<br /> <br /> Existen dos alternativas m&aacute;s para utilizar cualquier fuente, una se conoce como sIFR y consiste en realizar el remplazo de las fuentes mediante flash. Y la otra alternativa es Cuf&oacute;n, la cu&aacute;l utiliza javascript y la etiqueta canvas para remplazar cualquier texto por la fuente nueva, y es la que m&aacute;s se utiliza a d&iacute;a de hoy por no requerir plugins, tener una gran compatiblidad con todos los navegadores, ser f&aacute;cil de usar y tener una gran velocidad incluso con grandes textos.<br /> <br /> Para utilizar cuf&oacute;n tenemos que convertir nuestra fuente True Type a SVG, para a su vez convertirla en VML (lenguaje de marcas vectorizado), y obtener finalmente un json con cierta funcionalidad. Esto lo podemos hacer desde la <a href="http://cufon.shoqolate.com/generate/">Web de Cuf&oacute;n</a> de manera sencilla y r&aacute;pida.<br /> <br /> Las ventajas de Cuf&oacute;n son claras, permite cargar cualquier fuente con tan solo incluir un script en nuestra p&aacute;gina web. Y para el renderizado se utiliza VML para Internet Explorer y la etiqueta canvas de HTML 5 para el resto de navegadores.<br /> <br /> A continuaci&oacute;n un ejemplo de c&oacute;digo para utilizar Cuf&oacute;n:<br /> Lo primero es declarar el script de cufon qu&eacute; podemos descargar de su web.<br />
<pre class="code">	<script src="/imaginanet/cufon-yui.js" type="text/javascript"><!--mce:0--></script>
</pre>
<br /> Despu&eacute;s colocamos el json de la fuente generada, el cu&aacute;l se genera utilizando el generador de la web de Cuf&oacute;n.<br />
<pre class="code">	<script src="/imaginanet/YourFont.font.js" type="text/javascript"><!--mce:1--></script>
</pre>
<br /> Y ya simplemente remplazamos las etiquetas o textos deseados, colocando en una etiqueta script el c&oacute;digo, en el ejemplo se hace un replace para la etiqueta h1 y para el id sub1.<br />
<pre class="code">	Cufon.replace('h1');
	Cufon.replace('#sub1');
</pre>
<br />
<pre class="code">	<h1>Texto a remplazar con la nueva fuente</h1>
</pre>
<br /> Cuf&oacute;n adem&aacute;s soporta selectores de jQuery o cualquier otro framework de javascript, pero para poder utilizarlos deberemos incluir jQuery o el utilizado en nuestra web.<br /> <br /> Finalmente comentar que la directiva @font-family de CSS requiere navegadores con soporte de CSS3, y tiene la ventaja de permitirnos copiar el texto al portapapeles, cosa que con Cuf&oacute;n no podemos hacer. Ahora bien si quieres utilizar cualquier fuente en navegadores antiguos debes utilizar Cuf&oacute;n, pues estos no soportan la directiva font-family.]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=68</wfw:commentRss>
			<slash:comments>4</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/como-utilizar-cualquier-fuente-tipografia-en-nuestra-pagina-web.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Expresiones regulares con PHP y Javascript</title>
			<link>http://www.imaginanet.com/blog/expresiones-regulares-con-php-y-javascript.html</link>
			<guid>http://www.imaginanet.com/blog/expresiones-regulares-con-php-y-javascript.html</guid>
			<comments>http://www.imaginanet.com/blog/expresiones-regulares-con-php-y-javascript.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Thu, 31 Mar 2011 15:53:21 +0100</pubDate>
					<category><![CDATA[PHP]]></category>
					<category><![CDATA[JavaScript]]></category>
					<description><![CDATA[Las expresiones regulares son un mecanismo que nos permite realizar b&uacute;squedas y reemplazos de textos complejos.&nbsp;
Por ejemplo podr&iacute;amos sustituir todas las ocurrencias del texto  "www.yahoo.com" por "www.google.com" utilizando la siguiente expresi&oacute;n  regular en...]]></description>
			<content:encoded><![CDATA[><p>Las expresiones regulares son un mecanismo que nos permite realizar b&uacute;squedas y reemplazos de textos complejos.&nbsp;</p>
<p>Por ejemplo podr&iacute;amos sustituir todas las ocurrencias del texto  "www.yahoo.com" por "www.google.com" utilizando la siguiente expresi&oacute;n  regular en javascript:&nbsp;</p>
<p>texto.replace(/www.yahoo.com/gi,"www.google.com")</p>
<p>El lenguage PERL es el que ha hecho crecer a las expresiones regulares hasta llegar a ser lo que conocemos hoy. En PHP y javascript se contruyen los patrones de forma similar, con Javascript podemos aprovecharnos de ellas mediante los m&eacute;todos del objeto string, y en php con funciones como preg_search o preg_replace.</p>
<p>&nbsp;</p>
<table border="0" align="left">
<tbody>
<tr>
<td colspan="2" align="left" valign="top"><strong>Para crear patrones tenemos los siguientes caracteres comod&iacute;n:</strong></td>
</tr>
<tr>
<td align="left" valign="top">&nbsp;</td>
<td align="left" valign="top">Marca de car&aacute;cter especial</td>
</tr>
<tr>
<td align="left" valign="top">^</td>
<td align="left" valign="top">Comienzo de l&iacute;nea / Negaci&oacute;n cuando est&aacute; dentro de ( ) o [ ]</td>
</tr>
<tr>
<td align="left" valign="top">$</td>
<td align="left" valign="top">Final de l&iacute;nea</td>
</tr>
<tr>
<td align="left" valign="top">.</td>
<td align="left" valign="top">Cualquier car&aacute;cter salvo el salto de l&iacute;nea</td>
</tr>
<tr>
<td align="left" valign="top">|</td>
<td align="left" valign="top">Para indicar opciones</td>
</tr>
<tr>
<td align="left" valign="top">( )</td>
<td align="left" valign="top">Para agrupar caracteres</td>
</tr>
<tr>
<td align="left" valign="top">[ ]</td>
<td align="left" valign="top">Conjunto de caracteres opcionales</td>
</tr>
<tr>
<td colspan="2" align="left" valign="top">&nbsp;</td>
</tr>
<tr>
<td colspan="2" align="left" valign="top"><strong>Modificadores. Cada modificador act&uacute;a sobre        el car&aacute;cter o el par&eacute;ntesis inmediatamente anterior.</strong></td>
</tr>
<tr>
<td align="left" valign="top">*</td>
<td align="left" valign="top">Aparece 0 o m&aacute;s veces</td>
</tr>
<tr>
<td align="left" valign="top">+</td>
<td align="left" valign="top">1 o m&aacute;s veces</td>
</tr>
<tr>
<td align="left" valign="top">?</td>
<td align="left" valign="top">1 &oacute; 0 veces</td>
</tr>
<tr>
<td align="left" valign="top">{n}</td>
<td align="left" valign="top">Exactamente n veces</td>
</tr>
<tr>
<td align="left" valign="top">{n,}</td>
<td align="left" valign="top">n veces o m&aacute;s</td>
</tr>
<tr>
<td align="left" valign="top">{n,m}</td>
<td align="left" valign="top">Entre m y n</td>
</tr>
<tr>
<td colspan="2" align="left" valign="top">&nbsp;</td>
</tr>
<tr>
<td colspan="2" align="left" valign="top"><strong>Caracteres especiales</strong></td>
</tr>
<tr>
<td align="left" valign="top">&#92;b</td>
<td align="left" valign="top">Principio o fin de palabra</td>
</tr>
<tr>
<td align="left" valign="top">&#92;B</td>
<td align="left" valign="top">Marca la frontera en una palabra</td>
</tr>
<tr>
<td align="left" valign="top">&#92;d</td>
<td align="left" valign="top">D&iacute;gito</td>
</tr>
<tr>
<td align="left" valign="top">&#92;D</td>
<td align="left" valign="top">Car&aacute;cter alfab&eacute;tico</td>
</tr>
<tr>
<td align="left" valign="top">&#92;O</td>
<td align="left" valign="top">Car&aacute;cter nulo</td>
</tr>
<tr>
<td align="left" valign="top">&#92;t</td>
<td align="left" valign="top">Tabulador</td>
</tr>
<tr>
<td align="left" valign="top">&#92;f</td>
<td align="left" valign="top">Salto de p&aacute;gina</td>
</tr>
<tr>
<td align="left" valign="top">&#92;n</td>
<td align="left" valign="top">Salto de l&iacute;nea</td>
</tr>
<tr>
<td align="left" valign="top">&#92;w</td>
<td align="left" valign="top">Car&aacute;cter alfanum&eacute;rico [a-zA-Z0-9_ ]</td>
</tr>
<tr>
<td align="left" valign="top">&#92;W</td>
<td align="left" valign="top">Lo contrario a w ([^a-zA-Z0-9_ ])</td>
</tr>
<tr>
<td align="left" valign="top">&#92;s</td>
<td align="left" valign="top">Espacio</td>
</tr>
<tr>
<td align="left" valign="top">&#92;S</td>
<td align="left" valign="top">Lo contrario a espacio</td>
</tr>
<tr>
<td align="left" valign="top">&#92;cX</td>
<td align="left" valign="top">car&aacute;cter de control X</td>
</tr>
<tr>
<td align="left" valign="top">&#92;oNN</td>
<td align="left" valign="top">car&aacute;cter octal NN</td>
</tr>
<tr>
<td align="left" valign="top">&#92;xHH</td>
<td align="left" valign="top">hexadecimal HH</td>
</tr>
<tr>
<td colspan="2" align="left" valign="top">&nbsp;</td>
</tr>
<tr>
<td colspan="2" align="left" valign="top"><strong>Al final del patr&oacute;n tambi&eacute;n podemos utilizar modificadores</strong></td>
</tr>
<tr>
<td align="left" valign="top">i</td>
<td align="left" valign="top">El patr&oacute;n es indiferente a may&uacute;sculas o min&uacute;sculas</td>
</tr>
<tr>
<td align="left" valign="top">g</td>
<td align="left" valign="top">Busca todas las ocurrencias del patr&oacute;n</td>
</tr>
</tbody>
</table>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p><br /></p>

<p><strong>Algunas expresiones regulares &uacute;tiles:</strong></p>
<table border="0">
	<tbody>
	<tr>
		<td valign="top" style="padding: 0 0 10px 0;">/(http)[s?]://)/gi</td>
		<td valign="top">Busca todas las palabras que contengan http:// o https://, insensible a may&uacute;sculas</td>
	</tr>
	<tr>
		<td valign="top" style="padding: 0 0 10px 0;">/[&#92;w-&#92;.]{3,}@([&#92;w-]{2,}&#92;.)*([&#92;w-]{2,}&#92;.)[&#92;w-]{2,4}/</td>
		<td valign="top">Para validar emails</td>
	</tr>
	<tr>
		<td valign="top" style="padding: 0 0 10px 0;">^(ht|f)tp(s?)&#92;:&#92;/&#92;/[0-9a-zA-Z]([-.&#92;w]*[0-9a-zA-Z])*(:(0-9)*)*(&#92;/?)( [a-zA-Z0-9&#92;-&#92;.&#92;?&#92;,&#92;'&#92;/&#92;&#92;&#92;+&%&#92;$#_]*)?$</td>
		<td valign="top">Para validar urls</td>
	</tr>
	<tr>
		<td valign="top" style="padding: 0 0 10px 0;">/^[#]$([a-f0-9]{3})|([a-f0-9]{6})$/i</td>
		<td valign="top">Para validar un color en formato html</td>
	</tr>
	</tbody>
</table>

<p><br /></p>
<p><br /></p>
</table>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=67</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/expresiones-regulares-con-php-y-javascript.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Leer correo con PHP</title>
			<link>http://www.imaginanet.com/blog/leer-correo-con-php.html</link>
			<guid>http://www.imaginanet.com/blog/leer-correo-con-php.html</guid>
			<comments>http://www.imaginanet.com/blog/leer-correo-con-php.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Thu, 31 Mar 2011 09:34:25 +0100</pubDate>
					<category><![CDATA[PHP]]></category>
					<description><![CDATA[Suele ser muy com&uacute;n en una web el env&iacute;o de correos electr&oacute;nicos mediante la funci&oacute;n mail de PHP, ahora bien puede ser que a veces necesitemos leer correos desde PHP, ya sea para crear una aplicaci&oacute;n de webmail, o para mostrar al usuario sus correos recibidos, o cualquier otra funcionalidad que se...]]></description>
			<content:encoded><![CDATA[><p>Suele ser muy com&uacute;n en una web el env&iacute;o de correos electr&oacute;nicos mediante la funci&oacute;n mail de PHP, ahora bien puede ser que a veces necesitemos leer correos desde PHP, ya sea para crear una aplicaci&oacute;n de webmail, o para mostrar al usuario sus correos recibidos, o cualquier otra funcionalidad que se nos ocurra.</p>
<p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://www.imaginanet.com/ftp/articulos_web/phpmail.png" alt="Leer correo con PHP" width="250" height="132" /><br /><br />Para lograr esto, tenemos dos formas de hacerlo:<br /> <em>1) <strong>Implementar el protocolo directamente a trav&eacute;s de sockets</strong>.</em><br /> Puede que sea la forma m&aacute;s laboriosa pero en algunos casos, puede ser &uacute;til. Como hemos dicho se trata de abrir un socket al servidor de correo y comunicarnos con &eacute;l utilizando el protocolo requerido, donde los m&aacute;s comunes son POP3 e IMAP.<br /> <br /> Por ejemplo, para crear el socket har&iacute;amos:</p>
<pre class="code">$server = "ip del servidor";
$user = "usuario de correo";
$pass = "contrase&ntilde;a del correo";
$connection = fsockopen($server, 110, $errno, $errstr, 30);</pre>
A destacar que aqu&iacute; abrimos la conexi&oacute;n al puerto 110 (correspondiente a POP3).<br /> <br /> Para logearnos en el servidor de correo, bastar&iacute;a con hacer lo siguiente:<br />
<pre class="code">fputs($connection, "user $usern");
echo fgets($connection)."<br />";
fputs($connection, "pass $passn");
echo fgets($connection)."<br />";</pre>
Como podemos ver se trata de env&iacute;ar un mensaje y esperar una respuesta.<br /> <br /> Los mensajes que env&iacute;amos y el orden en que se env&iacute;an los marca el protocolo a utilizar en este caso POP3, as&iacute; que por ejemplo si queremos recibir el correo n&uacute;mero 2 debemos enviar lo siguiente:<br />
<pre class="code">fputs($connection, "RETR 2n");
$total = 0;
$bloque = 1000;
while ($total &lt; $tamano) {
    echo fread($connection, $bloque);
    $total = $total + $bloque;
}</pre>
Se env&iacute;a el mensaje RETR 2, con lo cual el servidor de correo nos manda el mensaje n&uacute;mero 2, y procedemos a leerlo. El tama&ntilde;o del mensaje a leer, lo obtenemos mandadole previamente el mensaje LIST 2.<br /> <br /> <em>2) La forma m&aacute;s sencilla y recomendada, consiste en utilizar <strong>las funciones IMAP</strong> que nos proporciona PHP. Estas permiten conectar con POP3, IMAP y NNTP</em>.<br /> En este caso si queremos abrir una conexi&oacute;n POP3 como antes, tendremos que utilizar la funci&oacute;n imap_open:<br />
<pre class="code">$mbox = imap_open ("{localhost:110/pop3}INBOX", "user_id", "password");</pre>
<br />Para obtener el numero de mensajes se utiliza imap_check, y para leer la cabecera de un mensaje por si queremos ver qui&eacute;n lo ha enviado, se utiliza la funci&oacute;n:<br />
<pre class="code">$cabecera = imap_headerinfo($mbox, numero_mensaje)
$from = $cabecera-&gt;from;
$subject = $cabecera-&gt;subject;</pre>
Para leer ya el mensaje en s&iacute;, utilizamos la funci&oacute;n imap_fetchstructure, pasandole como parametros la conexi&oacute;n abierta ($mbox), y el n&uacute;mero del mensaje.<br /> De esta forma obtenemos todas las partes que contiene el mensaje de correo electr&oacute;nico, pudiendo ser estas texto plano, html...<br /> <br /> Otras funciones &uacute;tiles son imap_delete, que nos permite eliminar un mensaje, e imap_expunge que hace efectivos los cambios, por ejemplo borra finalmente los mensajes marcados con delete.<br /> <br /> A destacar que las funciones IMAP al conectar a una cuenta de POP3 no disponen de toda su funcionalidad, es decir no podemos marcar mensajes como le&iacute;dos, ni manejar carpetas, ...]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=66</wfw:commentRss>
			<slash:comments>2</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/leer-correo-con-php.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Creando documentos PDFs dinámicos con PHP</title>
			<link>http://www.imaginanet.com/blog/creando-documentos-pdfs-dinamicos-con-php.html</link>
			<guid>http://www.imaginanet.com/blog/creando-documentos-pdfs-dinamicos-con-php.html</guid>
			<comments>http://www.imaginanet.com/blog/creando-documentos-pdfs-dinamicos-con-php.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Wed, 30 Mar 2011 16:15:47 +0100</pubDate>
					<category><![CDATA[PHP]]></category>
					<category><![CDATA[XHTML]]></category>
					<description><![CDATA[Cuando tenemos una aplicaci&oacute;n web, es muy com&uacute;n que tengamos que generar un archivo PDF con datos extra&iacute;dos de una base de datos para crear por ejemplo: informes, cat&aacute;logos, facturas, documentos, etc.El uso de algunas de estas librer&iacute;as para PHP puede llegar a ser demasiado complicado, as&iacute;...]]></description>
			<content:encoded><![CDATA[><p>Cuando tenemos una aplicaci&oacute;n web, es muy com&uacute;n que tengamos que generar un archivo PDF con datos extra&iacute;dos de una base de datos para crear por ejemplo: informes, cat&aacute;logos, facturas, documentos, etc.<br /><br />El uso de algunas de estas librer&iacute;as para PHP puede llegar a ser demasiado complicado, as&iacute; que vamos a hacer uso de la librer&iacute;a <strong>mPDF</strong> que nos permite <span style="text-decoration: underline;">generar PDFs en base a un c&oacute;digo HTML y CSS</span>.<br /><br />Los resultados que vamos a obtener van a ser muy buenos en funci&oacute;n del c&oacute;digo HTML usado, aunque tambi&eacute;n podemos usar otras librer&iacute;as m&aacute;s complejas pero con resultados m&aacute;s profesionales como es el caso de ezPDF, aunque para un sencillo ejemplo mPDF nos ser&aacute; suficiente.<br /><br /></p>
<h2>Generando PDFs din&aacute;micos con mPDF en base a un c&oacute;digo HTML y CSS</h2>
<br />Con mPDF podemos seleccionar m&uacute;ltiples opciones, como la resoluci&oacute;n del documento generado, a&ntilde;adir fuentes propias o incluso hacer uso de CSS3. A continuaci&oacute;n vamos a mostrar un peque&ntilde;o ejemplo que especificamos la cabecera, cuerpo y pie del documento.<br /><br />
<pre class="code php">&lt;?php

$cabecera = "&lt;span&gt;&lt;b&gt;Mi primer documento PDF din&aacute;mico con mPDF&lt;/b&gt;&lt;/span&gt;";

$cuerpo = "&lt;html&gt;
&lt;body&gt;
&lt;br/&gt;
&lt;h1&gt;&iexcl;Hola mundo!&lt;/h1&gt;
&lt;br/&gt;
&lt;div&gt;
&lt;p&gt;A continuaci&oacute;n mostramos algunos &lt;u&gt;datos&lt;/u&gt;&lt;/p&gt;
&lt;table style='width:200px;text-align:center;'&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;A&lt;/th&gt;
&lt;th&gt;B&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;						
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;						
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p&gt;Aqu&iacute; podemos introducir datos din&aacute;micos desde PHP&lt;/p&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;";

$pie = "&lt;span&gt;
&lt;a href=\&quot;http://www.imaginanet.com\&quot;&gt;Dise&ntilde;o y Programaci&oacute;n Web: Imaginanet&lt;/a&gt;
 - &lt;i&gt;Creado &quot;.date(&quot;d/m/Y&quot;).&quot;&lt;/i&gt;
&lt;/span&gt;";

include("mpdf/mpdf.php");
$mpdf=new mPDF();
$mpdf-&gt;SetHTMLHeader($cabecera);
$mpdf-&gt;SetHTMLFooter($pie);
$mpdf-&gt;WriteHTML($cuerpo);
$mpdf-&gt;Output();

?&gt;</pre>
<p>&nbsp;</p>
<p>Como podemos ver, es m&aacute;s complicado la maquetaci&oacute;n que el uso de PHP. En la maquetaci&oacute;n podemos hacer uso de todos los tags HTML, aunque no tienen un comportamiento 100% al de un navegador, as&iacute; que deberemos adaptarnos a la salida que mPDF produce.</p>
<p>Pod&eacute;is ver el resultado final del documento PDF <a title="PDF din&aacute;mico generado mediante PHP" href="http://www.imaginanet.com/ftp/articulos_web/documento_dinamico_php_pdf.pdf">generado din&aacute;micamente mediante PHP en este enlace</a>.</p>
<h2>Automatizando nuestro script</h2>
Es muy com&uacute;n que cuando generamos un  cat&aacute;logo este sea muy pesado. Mediante mPDF, si se trata de un cat&aacute;logo  de unas cincuenta p&aacute;ginas puede tardar f&aacute;cilmente unos 30 o 40 segundos  en generarlo si este tiene un buen n&uacute;mero de im&aacute;genes. Si nuestra web  tiene una gran cantidad de tr&aacute;fico y sumado a indexaci&oacute;n que realizan  los buscadores, puede afectar al rendimiento de nuestro servidor.<br /><br />Para  solucionarlo, una buena opci&oacute;n es generar estos documentos  autom&aacute;ticamente cada cierto tiempo, como por ejemplo una vez a la semana  o una vez al d&iacute;a, y que la descarga se produzca sobre un archivo  est&aacute;tico.<br /><br />
<h3><strong>Linux</strong></h3>
<br />Vamos a hacer uso de la herramienta  crontab, un sencillo ejemplo podr&iacute;a ser a&ntilde;adir la siguiente l&iacute;nea a  nuestro archivo /etc/crontab:<br /><br />
<pre class="code">50 8 * * 1 root php /var/www/vhosts/test-domain.yy/httpdocs/cron/generacion_pdf.php
</pre>
<p><br />Esto  ejecutar&iacute;a todos los lunes a las 8:50 de la ma&ntilde;ana el archivo  /var/www/vhosts/test-domain.yy/httpdocs/cron/generacion_pdf.php como el  usuario root.<br /><strong>&nbsp;</strong></p>
<h3><strong>Plesk</strong></h3>
<p>Dentro del dominio donde corra nuestro script, tenemos un apartado de tareas programadas que guarda el mismo formato que el crontab de Linux.</p>
<h2>Enlaces relacionados</h2>
<ul>
<li><a title="Librer&iacute;a PHP mPDF" href="http://mpdf.bpm1.com/" target="_blank">mPDF</a></li>
<li><a title="Librer&iacute;a PHP ezPDF" href="http://www.ros.co.nz/pdf/" target="_blank">ezPDF</a></li>
<li><a title="Linux Crontab" href="http://es.wikipedia.org/wiki/Cron_%28Unix%29" target="_blank">Cron</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=65</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/creando-documentos-pdfs-dinamicos-con-php.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Cómo maquetar con CSS y capas una web</title>
			<link>http://www.imaginanet.com/blog/como-maquetar-con-css-y-capas-una-web.html</link>
			<guid>http://www.imaginanet.com/blog/como-maquetar-con-css-y-capas-una-web.html</guid>
			<comments>http://www.imaginanet.com/blog/como-maquetar-con-css-y-capas-una-web.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Tue,  1 Mar 2011 09:28:11 +0100</pubDate>
					<category><![CDATA[CSS]]></category>
					<category><![CDATA[XHTML]]></category>
					<description><![CDATA[En esta entrada vamos a ver como olvidarnos de las tablas para maquetar, ya que mostraremos como crear un t&iacute;pica web con cabecera, contenido y menu lateral, y pie utilizando solo capas y CSS.Primeramente recordemos como se hac&iacute;a esto con tablas, para as&iacute; poder apreciar la mayor sencillez de utilizar CSS con...]]></description>
			<content:encoded><![CDATA[>En esta entrada vamos a ver como olvidarnos de las tablas para maquetar, ya que mostraremos como crear un t&iacute;pica web con cabecera, contenido y menu lateral, y pie utilizando solo capas y CSS.<br /><br />Primeramente recordemos como se hac&iacute;a esto con tablas, para as&iacute; poder apreciar la mayor sencillez de utilizar CSS con capas:<br />
<pre class="code">&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;
&nbsp;&nbsp; &nbsp;&lt;table&gt;&lt;tr&gt;&lt;td&gt;Cabecera&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&lt;/td&gt;
&nbsp;&nbsp; &nbsp;&lt;/tr&gt;
&nbsp;&nbsp; &nbsp;&lt;tr&gt;
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&lt;td&gt;
&nbsp;&nbsp; &nbsp;&lt;table&gt;&lt;tr&gt;
&lt;td&gt;Menu Lateral Izquierdo&lt;/td&gt;
&lt;td&gt;Contenido&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&lt;/td&gt;
&nbsp;&nbsp; &nbsp;&lt;/tr&gt;
&nbsp;&nbsp; &nbsp;&lt;tr&gt;
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&lt;td&gt;
&nbsp;&nbsp; &nbsp;&lt;table&gt;&lt;tr&gt;&lt;td&gt;Pie&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&lt;/td&gt;
&nbsp;&nbsp; &nbsp;&lt;/tr&gt;
&lt;/table&gt;</pre>
<br />Faltar&iacute;a definir anchuras de las tablas anteriores, pero no vamos a entrar en detalle con las tablas. Ahora aplicando capas tendr&iacute;amos el siguiente c&oacute;digo:<br />
<pre class="code">&lt;div id="cabecera"&gt;
&nbsp;&nbsp; &nbsp;Cabecera
&lt;/div&gt;
&lt;div id="menulateral"&gt;
&nbsp;&nbsp; &nbsp;Menu Lateral Izquierdo
&lt;/div&gt;
&lt;div id="contenido"&gt;
&nbsp;&nbsp; &nbsp;Contenido
&lt;/div&gt;
&lt;div id="pie"&gt;
&nbsp;&nbsp; &nbsp;Pie
&lt;/div&gt;</pre>
<br />Se puede apreciar ya una mayor sencillez. Los campos id de las capas (etiquetas div) son utlizados para dar estilos con CSS tal y como vemos a continuaci&oacute;n:<br />Primero le damos una anchura y altura fija a la cabecera, adem&aacute;s de un color al fondo para apreciar claramente la posici&oacute;n de la capa.<br />
<pre class="code">#cabecera {
&nbsp;&nbsp; &nbsp;width: 600px;
&nbsp;&nbsp; &nbsp;height: 100px;
&nbsp;&nbsp; &nbsp;background: green;
}</pre>
<br />Ahora al menu lateral y al contenido les hacemos lo mismo, anchura, altura y color de background, pero adem&aacute;s a&ntilde;adimos la propiedad float con valor left. Esto le dice a ambos elementos que se coloquen como flotantes a la izquierda. En otras palabras nos permite por en una misma "l&iacute;nea" dos elementos de tipo bloque como son las capas (div).<br />
<pre class="code">#menulateral {
&nbsp;&nbsp; &nbsp;float: left;
&nbsp;&nbsp; &nbsp;width: 250px;
&nbsp;&nbsp; &nbsp;height: 100px;
&nbsp;&nbsp; &nbsp;background: yellow;
}
#contenido {
&nbsp;&nbsp; &nbsp;float: left;
&nbsp;&nbsp; &nbsp;width: 350px;
&nbsp;&nbsp; &nbsp;height: 200px;
&nbsp;&nbsp; &nbsp;background: blue;
}</pre>
<br />Finalmente al pie le damos tambi&eacute;n anchura,altura y color de background, y le a&ntilde;adimos la propiedad clear con el valor left, cuyo significado es no permitir elementos flotantes por la izquierda de este elemento. Por tanto el pie aparecera en una l&iacute;nea nueva, debajo del menu lateral y el contenido.<br />
<pre class="code">#pie {
&nbsp;&nbsp; &nbsp;width: 600px;
&nbsp;&nbsp; &nbsp;height: 50px;
&nbsp;&nbsp; &nbsp;background: cyan;
&nbsp;&nbsp; &nbsp;clear: left;
}</pre>
<br />Para apreciar mejor dicho comportamiento podemos cambiar la propiedad float de la capa contenido y poner la propiedad float con el valor "right", de esta manera la capa aparece desplaza a la esquina derecha del navegador, y se ve como "flota" sobre el elemento pie, es decir, como sobrepasa la l&iacute;nea que ocupa el pie. Para solucionar esto tendremos que cambiar la propiedad clear del pie y ponerle el valor "both", para as&iacute; no permitir elementos flotantes ni a izquierda, ni a derecha.<br /><br />Para poder centrar la p&aacute;gina web, se suele englobar todas las capas en una capa contenedora que ser&aacute; la que centremos, es decir, ponemos:<br />
<pre class="code">&lt;div id="contenedor"&gt;
&nbsp;&nbsp; &nbsp;...c&oacute;digo de capas anterior...
&lt;/div&gt;</pre>
<br />Ahora para poder centrar la capa contenedora debemos definirle una anchura, pues por defecto tiene toda la anchura disponible, y es por ello que los elementos con float right aparecen pegados a la derecha, por ello le aplicamos el siguiente c&oacute;digo CSS:<br />
<pre class="code">#contenedor {
&nbsp;&nbsp; &nbsp;width: 600px;
&nbsp;&nbsp; &nbsp;margin: 0 auto;
}</pre>
<br />Aqu&iacute; adem&aacute;s de la anchura le definimos la propiedad margin (margen), con valor 0 para el top y bottom, y auto para izquierda y derecha. Este auto provocar&aacute; que la capa contenedora se centre.<br /><br />Una buena pr&aacute;ctica para maquetar es realizar previamente un reseteo de los estilos, puesto que no todos los navegadores utilizan los mismo valores por defecto para cada etiqueta, por ello nos podemos encontrar con qu&eacute; se vea diferente nuestra p&aacute;gina en distintos navegadores. Con un reseteo se evitan gran parte de estas posibles diferencias.<br /><br />Aqu&iacute; un ejemplo de reseteo:<br />
<pre class="code">html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, font, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td {
&nbsp;&nbsp; &nbsp;margin: 0;
&nbsp;&nbsp; &nbsp;padding: 0;
&nbsp;&nbsp; &nbsp;border: 0;
&nbsp;&nbsp; &nbsp;outline: 0;
&nbsp;&nbsp; &nbsp;font-size: 100%;
&nbsp;&nbsp; &nbsp;vertical-align: baseline;
&nbsp;&nbsp; &nbsp;background: transparent;
}</pre>
<br />Si probamos este c&oacute;digo tal c&uacute;al en Internet Explorer podremos ver que no se centra a no ser que definamos el doctype del documento, por ello siempre es recomendable ponerlo:<br />
<pre class="code">&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;/head&gt;
&lt;body&gt;
&nbsp;&nbsp; &nbsp;...c&oacute;digo anterior de capas...
&lt;/body&gt;
&lt;/html&gt;</pre>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=64</wfw:commentRss>
			<slash:comments>2</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/como-maquetar-con-css-y-capas-una-web.html</feedburner:origLink>
		</item>
				
		<item>
			<title>API de datos de Youtube</title>
			<link>http://www.imaginanet.com/blog/api-de-datos-de-youtube.html</link>
			<guid>http://www.imaginanet.com/blog/api-de-datos-de-youtube.html</guid>
			<comments>http://www.imaginanet.com/blog/api-de-datos-de-youtube.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Sun, 27 Feb 2011 22:06:55 +0100</pubDate>
					<category><![CDATA[Redes Sociales]]></category>
					<category><![CDATA[Web 2.0]]></category>
					<category><![CDATA[PHP]]></category>
					<description><![CDATA[Para crear aplicaciones relacionadas con youtube tenemos 2 APIs, API de datos y API del reproductor:
- El API de datos est&aacute; orientado a desarrolladores acostumbrados a programar en el lado del servidor. Yotube nos proporciona clases implementadas en varios lenguajes de programaci&oacute;n que nos podemos descargar.
- El API...]]></description>
			<content:encoded><![CDATA[><p>Para crear aplicaciones relacionadas con youtube tenemos <a href="http://code.google.com/intl/es-ES/apis/youtube/overview.html" target="_blank">2 APIs</a>, API de datos y API del reproductor:</p>
<p>- El API de datos est&aacute; orientado a desarrolladores acostumbrados a programar en el lado del servidor. Yotube nos proporciona clases implementadas en varios lenguajes de programaci&oacute;n que nos podemos descargar.</p>
<p>- El API del reproductor nos permite configurar las opciones del reproductor de youtube en nuestra web, creando incluso nuestros propios controles.</p>
<p>En este art&iacute;culo nos vamos a centrar en una descripci&oacute;n general del API de datos.</p>
<p>Esta API se basa en el protocolo <a href="http://www.imaginanet.com/blog/servidor-rest-con-php-y-peticiones-mediante-jquery-y-ajax.html">REST</a>, con peticiones HTTP y respuesta en formato XML, aunque tambi&eacute;n podemos obtener la respuesta en formato JSON a&ntilde;adiento a la petici&oacute;n el par&aacute;metro alt=jsonc.</p>
<p>Para autenticarnos disponemos de 3 esquemas: AuthSub, OAuth o ClientLogin.</p>
<p>- AuthSub: Para crear una aplicaci&oacute;n web que permita a los usuarios vincular v&iacute;deos, comentarios, puntuaciones, contactos u otra informaci&oacute;n con sus propias cuentas de YouTube.</p>
<p>- OAuth: Este m&eacute;todo se utiliza con la misma finalidad que el anterior pero utilizando un sistema est&aacute;ndar basado en el protocolo abierto <a href="http://oauth.net">OAuth</a></p>
<p>- ClientLogin: Para asociar todas las acciones de tu aplicaci&oacute;n a una cuenta de Youtube.</p>
<p>Si tu aplicaci&oacute;n requiere que sus usuarios introduzcan su usuario y contrase&ntilde;a de youtube, no deber&iacute;as usar el m&eacute;todo ClientLogin.</p>
<p>Para crear tu aplicaci&oacute;n tambi&eacute;n necesitar&aacute;s de una clave de desarrollador y un ID de cliente que puedes obtener <a href="http://code.google.com/apis/youtube/dashboard/" target="_blank">aqu&iacute;</a></p>
<p>En la <a href="http://code.google.com/intl/es-ES/apis/youtube/reference.html" target="_blank">gu&iacute;a de referencia</a> del API tienes informaci&oacute;n detallada sobre todas las acciones que puedes realizar y sobre los c&oacute;digos de respuesta HTTP para solicitudes del API de datos de YouTube.</p>
<p>Ahora vamos a ver unos ejemplos con PHP y curl de lo que podemos hacer utilizando este API:</p>
<p><strong>A&ntilde;adir un v&iacute;deo favorito a tu canal:</strong></p>
<p>En este ejemplo suponemos que estamos utilizando el m&eacute;todo de autenticaci&oacute;n ClientLogin. En las cabeceras de la petici&oacute;n POST debemos pasarle el m&eacute;todo de autenticaci&oacute;n y el "authtoken" que obtenemos al autenticarnos (AUTH_TOKEN), la clave de desarrollador (DEVELOPER_KEY). Tambi&eacute;n le estamos indicando que queremos los datos en formato JSON. En la variable $data tenemos que poner el id del video de youtube que queremos a&ntilde;adir como favorito a nuestro canal. como estamos utilizando un protocolo REST tenemos que enviarlo en el formato correspondiente, por eso las claves del array deben ser ["data"]["video"]["id"], este formato ser&aacute; el mismo que recibamos cuando hagamos una petici&oacute;n GET para obtener los videos favoritos de nuesto canal.</p>
<pre class="code php">	$data["data"]["video"]["id"] = 'ID_VIDEO';

	$ch = curl_init();

	curl_setopt($ch,CURLOPT_URL,'http://gdata.youtube.com/feeds/api/users/TU_CANAL/favorites?alt=jsonc');

	curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
	curl_setopt($ch, CURLOPT_POST, 1);
	curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
	curl_setopt($ch, CURLOPT_HTTPHEADER, array(
			"Host: gdata.youtube.com",
			"Content-Type: application/json",
			"Authorization: GoogleLogin auth=AUTH_TOKEN",
			"GData-Version: 2,
			"X-GData-Key: key=DEVELOPER_KEY"
	));
	$response = curl_exec($ch);
	$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
	curl_close($ch);
</pre>
<br />
<p><strong>Borrar un v&iacute;deo favorito de tu canal:</strong></p>
<p>Para borrar un video favorito de nuestro canal es muy simple, solo tenemos que enviar una petici&oacute;n DELETE a la url del video correspondiente. Para referenciar al video en la url utilizamos su ID.</p>
<pre class="code php">	$ch = curl_init('http://gdata.youtube.com/feeds/api/users/TU_CANAL/favorites/ID_VIDEO');
	curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($ch, CURLOPT_HTTPHEADER, array(
			"Host: gdata.youtube.com",
			"Content-Type: application/atom+xml",
			"Authorization: GoogleLogin auth=AUTH_TOKEN",
			"X-GData-Key: key=DEVELOPER_KEY"
	));
	$response = curl_exec($ch);
	$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
	curl_close($ch);
</pre>
<br />
<p><strong>Obtener los v&iacute;deos favoritos de tu canal:</strong></p>
<p>Obtener un listado con los v&iacute;deos favoritos de tu canal es mucho m&aacute;s simple. No necesitamos estar autenticados, pues esta acci&oacute;n es p&uacute;blica. As&iacute; que podemos utilizar la funci&oacute;n de php "file_get_contents". Si pasamos por GET el par&aacute;metro alt=jsonc, recibiremos la respuesta en JSON, por lo que parsearla ser&aacute; mucho m&aacute;s sencillo, solo hay que aplicarle la funci&oacute;n "json_decode" a la respuesta.</p>
<pre class="code php">	$response = file_get_contents("http://gdata.youtube.com/feeds/api/users/TU_CANAL/favorites?v=2&amp;alt=jsonc");
	$response = json_decode($response,true);
</pre>
<br />
<p>En la <a href="http://code.google.com/intl/es-ES/apis/youtube/reference.html" target="_blank">gu&iacute;a de referencia</a> del API tenemos los c&oacute;digos de respuesta de estas acciones, adem&aacute;s de una explicaci&oacute;n m&aacute;s detallada de lo que podemos hacer con esta API. En estos ejemplos hemos utilizado php y curl para hacer las peticiones, pero desde la web del API podemos descargarnos clases para distintos lenguajes de programaci&oacute;n que nos facilitar&aacute;n esta tarea.</p>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=63</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/api-de-datos-de-youtube.html</feedburner:origLink>
		</item>
				
		<item>
			<title>El tiempo en tu web mediante el API Google Weather</title>
			<link>http://www.imaginanet.com/blog/el-tiempo-en-tu-web-mediante-el-api-google-weather.html</link>
			<guid>http://www.imaginanet.com/blog/el-tiempo-en-tu-web-mediante-el-api-google-weather.html</guid>
			<comments>http://www.imaginanet.com/blog/el-tiempo-en-tu-web-mediante-el-api-google-weather.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Wed, 16 Feb 2011 13:03:12 +0100</pubDate>
					<category><![CDATA[PHP]]></category>
					<description><![CDATA[Mediante Google Weather podemos  mostrar un informe meteorol&oacute;gico para diferentes ciudades de manera personalizada del tiempo actual y una predicci&oacute;n de los d&iacute;as pr&oacute;ximos.
La llamada a Google Weather es una simple llamada a una URL pasando el par&aacute;metro de  ciudad, por ejemplo...]]></description>
			<content:encoded><![CDATA[>Mediante Google Weather podemos  mostrar un <strong>informe meteorol&oacute;gico</strong> para diferentes ciudades de manera personalizada del tiempo actual y una predicci&oacute;n de los d&iacute;as pr&oacute;ximos.
<p>La llamada a Google Weather es una simple llamada a una URL pasando el par&aacute;metro de  ciudad, por ejemplo <a href="http://www.google.com/ig/api?weather=Madrid">http://www.google.com/ig/api?weather=Madrid</a> devolvi&eacute;ndonos un XML (podemos probar a poner esta direcci&oacute;n en un navegador web para hacernos una idea).</p>
<p>El siguiente paso ser&iacute;a procesar el XML devuelto y mostrar los datos que nos interesen. Por ejemplo vamos a mostrar un c&oacute;digo en PHP para el <strong>API de Google Weather</strong> usando la librer&iacute;a <span style="text-decoration: underline;">SimpleXML</span>:</p>
<pre class="code php">&lt;?php
	// Proceso
	$ciudad = "Barcelona";

	$xml = simplexml_load_file("http://www.google.com/ig/api?weather=".$ciudad);

	if($xml===false) { // Fallo al contactar con Google
			return null;
	}

	$current = $xml-&gt;xpath("/xml_api_reply/weather/current_conditions"); 
	if(count($current)==0) { // Ciudad err&oacute;nea
			return null;
	}

	$temperatura_centigrados = $current[0]-&gt;temp_c["data"];
	$humedad = $current[0]-&gt;humidity["data"];
	$condiciones = $current[0]-&gt;condition["data"];
	$icono = $current[0]-&gt;icon["data"];
	
	// Vista
	echo 'Temperatura: '.$temperatura_centigrados.'&amp;deg;&lt;br/&gt;';
	echo $humedad.'&lt;br/&gt;';
	echo 'Condiciones: '.$condiciones.'&lt;br/&gt;';
	echo '&lt;img src="http://www.google.com/'.$icono.'" alt="'.$condiciones.'" title="'.$condiciones.'"/&gt;"';
	
?&gt;

</pre>
<p>Por &uacute;ltimo, para hacer nuestra aplicaci&oacute;n resistente a fallos, recomendamos ejecutar este script desde una llamada AJAX, ya que si Google fallara o tardara en responder, nuestra p&aacute;gina tardar&iacute;a o fallar&iacute;a al servirse.</p>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=62</wfw:commentRss>
			<slash:comments>10</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/el-tiempo-en-tu-web-mediante-el-api-google-weather.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Mostrar videos en capas superpuestas</title>
			<link>http://www.imaginanet.com/blog/mostrar-videos-en-capas-superpuestas.html</link>
			<guid>http://www.imaginanet.com/blog/mostrar-videos-en-capas-superpuestas.html</guid>
			<comments>http://www.imaginanet.com/blog/mostrar-videos-en-capas-superpuestas.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Thu, 28 Apr 2011 09:32:41 +0100</pubDate>
					<category><![CDATA[XHTML]]></category>
					<category><![CDATA[JavaScript]]></category>
					<category><![CDATA[CSS]]></category>
					<category><![CDATA[Internet Explorer]]></category>
					<description><![CDATA[Es posible que en alguna situaci&oacute;n tengamos dos videos superpuestos, ya sea porque tengamos un dise&ntilde;o con pesta&ntilde;as, o que incluso tengamos alguna ventana que haga de popup y deba mostrarse por encima de un video.  Para poder lograr que los videos se coloquen correctamente debemos pasarle el parametro...]]></description>
			<content:encoded><![CDATA[>Es posible que en alguna situaci&oacute;n tengamos dos videos superpuestos, ya sea porque tengamos un dise&ntilde;o con pesta&ntilde;as, o que incluso tengamos alguna ventana que haga de popup y deba mostrarse por encima de un video.<br /> <br /> Para poder lograr que los videos se coloquen correctamente debemos pasarle el parametro &ldquo;wmode&rdquo; con el valor &ldquo;transparent&rdquo; de esta forma no dar&aacute;n ning&uacute;n problema en Internet Explorer. Ahora bien para crear dos pesta&ntilde;as y que podamos tener ambos videos abiertos y cambiar entre ellos, podemos optar por la siguiente soluci&oacute;n:<br /> <br /> Colocar las capas con posici&oacute;n absoluta y jugar con la propiedad z-index para ir cambiando cu&aacute;l se muestra por encima de la otra, de esta forma podremos estar viendo los videos sin que al cambiar de pesta&ntilde;a vuelva a empezar la reproducci&oacute;n del video.<br />
<pre class="code"><div style="background: #CCC; width: 680px; position: relative;">
       <div>
           <a onclick="document.getElementById('parte2').style .zIndex='1';document.getElementById('parte1').style .zIndex='2';return false;" href="#">Video 1</a>
           <a onclick="document.getElementById('parte1').style .zIndex='1';document.getElementById('parte2').style .zIndex='2';return false;" href="#">Video 2</a>
       </div>
       <div id="parte1" style="z-index: 2; position: absolute; background: #090; width: 680px; text-align: center;">
           <iframe src="http://www.youtube.com/embed/mkUdQtINflw?wmode=transparent" width="640" height="390"></iframe>
       </div>
       <div id="parte2" style="z-index: 1; position: absolute; background: #009; width: 680px; text-align: center;">
           <iframe src="http://www.youtube.com/embed/Ezk0e1VL80o?wmode=transparent" width="640" height="390"></iframe>
       </div>
</div>
</pre>
<br /> Podemos ver el ejemplo en funcionamiento <a href="http://www.imaginanet.com/ftp/blog/videos.htm" target="_blank">aqu&iacute;</a>.]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=69</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/mostrar-videos-en-capas-superpuestas.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Servidor REST con PHP y peticiones mediante jquery y ajax.</title>
			<link>http://www.imaginanet.com/blog/servidor-rest-con-php-y-peticiones-mediante-jquery-y-ajax.html</link>
			<guid>http://www.imaginanet.com/blog/servidor-rest-con-php-y-peticiones-mediante-jquery-y-ajax.html</guid>
			<comments>http://www.imaginanet.com/blog/servidor-rest-con-php-y-peticiones-mediante-jquery-y-ajax.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Mon, 14 Feb 2011 20:45:36 +0100</pubDate>
					<category><![CDATA[PHP]]></category>
					<category><![CDATA[jQuery]]></category>
					<category><![CDATA[Ajax]]></category>
					<description><![CDATA[Un servidor REST (Representational State Transfer) puede ser muy &uacute;til para la creaci&oacute;n de aplicaciones HTML5. Utilizar&iacute;amos el servidor para el m&oacute;delo de datos y el cliente (navegador) para la l&oacute;gica de la aplicaci&oacute;n, realizando llamadas ajax al servidor que devolver&iacute;a los datos en...]]></description>
			<content:encoded><![CDATA[><p>Un servidor <strong>REST</strong> (Representational State Transfer) puede ser muy &uacute;til para la creaci&oacute;n de aplicaciones HTML5. Utilizar&iacute;amos el servidor para el m&oacute;delo de datos y el cliente (navegador) para la l&oacute;gica de la aplicaci&oacute;n, realizando llamadas ajax al servidor que devolver&iacute;a los datos en formato JSON, por ejemplo. En un sistema REST, cada recurso es direccionable &uacute;nicamente a trav&eacute;s de su URI, y disponemos de un conjunto de aplicaciones (<strong>POST</strong>, <strong>GET</strong>, <strong>PUT</strong> y <strong>DELETE</strong>), propias del protocolo HTTP, para trabajar con esos recursos.</p>
<p>Por ejemplo, si disponemos de una base de datos de clientes y queremos objetener una lista con ellos, tendr&iacute;amos que acceder a la URL del recurso "clientes", http://servidor.com/clientes. Una petici&oacute;n GET a este recurso nos devolver&iacute;a un array con todos los clientes que tenemos en nuestra BB.DD. Si lo que queremos es obtener la informaci&oacute;n de un cliente en particular, por ejemplo el cliente con identificador igual a 00001, har&iacute;amos una petici&oacute;n GET a la url http://servidor.com/clientes/00001. Para crear un cliente nuevo tendr&iacute;amos que enviar por POST una petici&oacute;n a http://servidor.com/clientes con los datos del nuevo cliente. Para modificar alg&uacute;n dato del cliente 00001 usar&iacute;amos una petici&oacute;n PUT con los nuevos datos a http://servidor.com/clientes/00001. Si la petici&oacute;n es DELETE a esa misma url, borrar&iacute;amos ese registro de la BB.DD. Normalmente los datos que devuelve el servidor estar&aacute;n en formato JSON o XML. Para nuestro ejemplo utilizaremos JSON, ideal para trabajar con aplicaciones javascript.</p>
<p>Para tratar mediante PHP las peticiones en nuestro servidor utilizaremos un c&oacute;digo parecido a este:</p>
<pre class="code php">$method = $_SERVER['REQUEST_METHOD'];

// tendremos que tratar esta variable para obtener el recurso adecuado de nuestro modelo.
$resource = $_SERVER['REQUEST_URI'];

// Dependiendo del m&eacute;todo de la petici&oacute;n ejecutaremos la acci&oacute;n correspondiente.
switch ($method) {
	case 'GET':
		// c&oacute;digo para m&eacute;todo GET
		break;
	case 'POST':
		$arguments = $_POST;
		// c&oacute;digo para m&eacute;todo POST
		break;
	case 'PUT':
		parse_str(file_get_contents('php://input'), $arguments);
		// c&oacute;digo para m&eacute;todo PUT
		break;
	case 'DELETE':
		// c&oacute;digo para m&eacute;todo DELETE
		break;
}
echo json_encode($response,true); // $response será un array con los datos de nuestra respuesta.
</pre>
<br />
<p>Utilizando jquery es muy sencillo realizar peticiones a nuestro servidor con la funci&oacute;n $.ajax:</p>
<pre class="code js">$.ajax({
	url: 'http://servidor.com/recurso', // url del recurso
	type: "get", // podr&iacute;a ser get, post, put o delete.
	data: {}, // datos a pasar al servidor, en caso de necesitarlo
	success: function (r) {
		// aqu&iacute; tratar&iacute;amos la respuesta del servidor
	}
});
</pre>
<br />
<p>Con estas simples indicaciones ya tenemos las bases para la construcci&oacute;n de una aplicaci&oacute;n. Si dise&ntilde;amos bien nuestro modelo de datos tendremos la oportunidad de crear gran variedad de aplicaciones para distintos tipos de clientes (navegadores web, m&oacute;viles, aplicaciones de escritorio ...), sin tener que modificar nuestro servidor, utilizando un m&eacute;todo estandar, sencillo e intuitivo.</p>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=61</wfw:commentRss>
			<slash:comments>8</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/servidor-rest-con-php-y-peticiones-mediante-jquery-y-ajax.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Como compartir contenidos con RSS en PHP</title>
			<link>http://www.imaginanet.com/blog/como-compartir-contenidos-con-rss-en-php.html</link>
			<guid>http://www.imaginanet.com/blog/como-compartir-contenidos-con-rss-en-php.html</guid>
			<comments>http://www.imaginanet.com/blog/como-compartir-contenidos-con-rss-en-php.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Wed,  2 Feb 2011 08:36:13 +0100</pubDate>
					<category><![CDATA[PHP]]></category>
					<category><![CDATA[RSS]]></category>
					<description><![CDATA[RSS (Really Simple Sindication) es un est&aacute;ndar con formato XML que permite compartir contenidos de una p&aacute;gina web. Facilitando incluso leer dichos contenidos sin disponer de un navegador web.
Para poder compartir el contenido se debe seguir el siguiente formato indicado por RSS (solo mostramos las etiquetas...]]></description>
			<content:encoded><![CDATA[><p>RSS (Really Simple Sindication) es un est&aacute;ndar con formato XML que permite compartir contenidos de una p&aacute;gina web. Facilitando incluso leer dichos contenidos sin disponer de un navegador web.</p>
<p><img style="display: block; margin-left: auto; margin-right: auto;" title="RSS" src="http://www.imaginanet.com/ftp/articulos_web/128px-Feed-icon.svg.png" alt="RSS" width="128" height="128" /><br />Para poder compartir el contenido se debe seguir el siguiente formato indicado por RSS (solo mostramos las etiquetas m&aacute;s comunes):</p>
<pre class="code">&lt;?xml version="1.0" encoding="Codificaci&oacute;n de nuestro texto del contenido o web"?&gt;
&lt;rss version="2.0"&gt;
&nbsp;&nbsp; &nbsp;&lt;channel&gt;
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&lt;title&gt;T&iacute;tulo de nuestro contenido o web&lt;/title&gt;
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&lt;link&gt;Enlace a nuestro contenido o web &lt;/link&gt;
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&lt;description&gt;Descripci&oacute;n del contenido o web&lt;/description&gt;
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&lt;language&gt;Idioma del contenido o web&lt;/language&gt;

&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&lt;item&gt;
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&lt;title&gt;Titulo del item&lt;/title&gt;
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&lt;link&gt;Enlace del item &lt;/link&gt;
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&lt;pubDate&gt;Fecha de publicaci&oacute;n del item&lt;/pubDate&gt;
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&lt;description&gt;Descripci&oacute;n del item&lt;/description&gt;
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&lt;/item&gt;
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&lt;item&gt;
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;...
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&lt;/item&gt;
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;...
&nbsp;&nbsp; &nbsp;&lt;/channel&gt;
&lt;/rss&gt;
</pre>
Como podemos apreciar, si por ejemplo queremos compartir las noticias de un blog, se debe crear un item por cada una de ellas.<br /><br />No vamos a entrar en detalle de como generar los datos necesarios, pero lo normal es obtenerlos de una base de datos a trav&eacute;s de una serie de consultas SQL. Ahora bien una vez tengamos nuestros datos generados, hay que tener en cuenta lo siguiente:<br /><br />- La codificaci&oacute;n a indicar en la cabecera de xml, debe ser la misma que la codificaci&oacute;n usada para almacenar nuestros datos, siendo las m&aacute;s comunes ISO-8859-1 y UTF-8.<br />- Para los datos como t&iacute;tulo y descripci&oacute;n, o cualquier otro campo cuyo contenido suela llevar etiquetas HTML, es necesario o bien eliminarlas utilizando funciones PHP como "htmlentities" o "strip_tags", o bien utilizar la etiqueta &lt;![CDATA[ ]]&gt; que hace que el contenido que tenga se ignore y no se procese como XML, permitiendo mostrar el contenido HTML.<br />- Si nuestro contenido tiene acentos no ser&aacute; suficiente con utilizar las funciones de PHP mencionadas, suponiendo que no se quisiera conservar las etiquetas HTML, sino que ser&aacute; necesario utilizar adem&aacute;s la etiqueta CDATA para escapar dichos car&aacute;cteres.<br /><br />En resumen si queremos conservar las etiquetas HTML o tenemos acentos utilizamos la etiqueta CDATA. Y si por el contrario no queremos etiquetas HTML, entonces utilizamos las funciones PHP citadas.<br />
<pre class="code">&nbsp;&nbsp; &nbsp;echo "&lt;title&gt;&lt;![CDATA[". $titulo ."]]&gt;&lt;/title&gt;";
&nbsp;&nbsp; &nbsp;echo "&lt;description&gt;&lt;![CDATA[". $texto ."]]&gt;&lt;/description&gt;";
</pre>
Siguiendo estos consejos &uacute;ltimos evitaremos errores de lectura XML, es decir, de XML mal formado.<br />]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=60</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/como-compartir-contenidos-con-rss-en-php.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Controlar los pagos por PayPal mediante Notificación de Pago Instantánea</title>
			<link>http://www.imaginanet.com/blog/controlar-los-pagos-por-paypal-mediante-notificacion-de-pago-instantanea.html</link>
			<guid>http://www.imaginanet.com/blog/controlar-los-pagos-por-paypal-mediante-notificacion-de-pago-instantanea.html</guid>
			<comments>http://www.imaginanet.com/blog/controlar-los-pagos-por-paypal-mediante-notificacion-de-pago-instantanea.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Fri, 14 Jan 2011 08:47:06 +0100</pubDate>
					<category><![CDATA[Comercio electrónico]]></category>
					<category><![CDATA[PHP]]></category>
					<description><![CDATA[Tras ver como realizar pagos por PayPal en una tienda virtual en tu web, el siguiente paso ser&iacute;a saber si finalmente el usuario realiz&oacute; el pago o no, ya que podr&iacute;a haber cerrado la ventana, no tener la tarjeta de cr&eacute;dito a mano o simplemente haberse arrepentido.
Verificando el pago de las compras en un...]]></description>
			<content:encoded><![CDATA[><p>Tras ver como <a title="Pagar mediante PayPal en tu p&aacute;gina web" href="http://www.imaginanet.com/blog/como-utilizar-paypal-para-realizar-compras-en-tu-web.html">realizar pagos por PayPal en una tienda virtual</a> en tu web, el siguiente paso ser&iacute;a saber si finalmente el usuario realiz&oacute; el pago o no, ya que podr&iacute;a haber cerrado la ventana, no tener la tarjeta de cr&eacute;dito a mano o simplemente haberse arrepentido.</p>
<h3>Verificando el pago de las compras en un comercio electr&oacute;nico mediante PayPal</h3>
<p>Como no sabemos si el cliente va a realmente a pagar tras ir a la pantalla de pago de PayPal, lo ideal es tratar cada compra como no pagada hasta que recibamos la confirmaci&oacute;n por parte de PayPal de que as&iacute; ha sido.</p>
<p>Para recibir la notificaci&oacute;n por parte de PayPal, deberemos activar la opci&oacute;n del <strong>Instant Payment Notification</strong> o <strong>Notificaci&oacute;n de Pago Instant&aacute;nea</strong> en el panel de control de tu cuenta y especificar la ruta de donde tiene que avisar con unos datos relativos a la compra que se ha realizado satisfactoriamente.</p>
<p>Este archivo al que PayPal avisa lo alojaremos en nuestro servidor y deber&aacute; ser programado a medida para realizar la acci&oacute;n que corresponda. En nuestro caso programaremos en PHP y la ruta de aviso por ejemplo podr&iacute;a ser http://www.mi-host-de-pruebas.com/paypal_ipn.php</p>
<p>La programaci&oacute;n del archivo paypal_ipn.php har&aacute; actualizar el estado en base de datos de ese pedido de no pagado a pagado.</p>
<h3>Configurando Instant Payment Notification en nuestra cuenta de PayPal</h3>
<p>Lo primero deberemos crear una cuenta <em>Premier</em> o <em>Business</em> de PayPal y acceder a ella. En la pantalla principal, deberemos estar en la pesta&ntilde;a "Mi cuenta", ir al submen&uacute; "Perfil" y elegir "M&aacute;s opciones".</p>
<p>En la nueva pantalla elegir la opci&oacute;n "Preferencias de Notificaci&oacute;n de pago instant&aacute;nea". Ahora rellenaremos el campo "URL de notificaci&oacute;n" con la direcci&oacute;n que nos interese (por ejemplo http://www.mi-host-de-pruebas.com/paypal_ipn.php), marcaremos la opci&oacute;n de "Recibir mensajes de IPN (activado)" y guardaremos los cambios.</p>
<h3>Programando la actualizado de la compra electr&oacute;nica con PHP</h3>
<p>Cuando se realiza un pago satisfactoriamente, PayPal nos env&iacute;a una serie de variables mediante POST con la que podemos identificar qu&eacute; pago se ha pagado satisfactoriamente, pero s&oacute;lo nos har&aacute;n falta dos:</p>
<ul>
<li><strong><em>payment_status</em></strong>: puede tener varios valores, pero los que nos interesan son s&oacute;lo dos, <em>Completed</em>, que significa que la transacci&oacute;n de dinero se ha completado, y <em>Processed</em>, indica que el pago ha sido aceptado pero no se ha completado a&uacute;n la transacci&oacute;n de dinero por que el banco del cliente a&uacute;n no ha hecho la transferencia de dinero (este caso tambi&eacute;n lo contemplamos como pago v&aacute;lido).</li>
<li><strong><em>item_number</em></strong>: esta variable es una de las que nuestra p&aacute;gina web env&iacute;o al redirigirnos a PayPal (lo podemos ver en la primera parte de como utilizar PayPal en nuestra p&aacute;gina web) y contiene un valor que identifique la compra que se ha pagado.</li>
</ul>
<p>Lo primero es comprobar que payment_status nos indica que se ha realizado un pago, a partir de ah&iacute; deberemos jugar con la variable item_number que puede tener m&uacute;ltiples usos. Si por ejemplo al llamar a PayPal indicamos que item_number es "VENTA-512", en la notificaci&oacute;n sabremos que la venta de identificador 512 se ha pagado satisfactoriamente.</p>
<p>Tambi&eacute;n podr&iacute;amos realizar distintos tipos de pago en nuestra web que no s&oacute;lo sea de venta, si no transacci&oacute;n, alquiler, etc. y siempre podr&iacute;amos identificarla mediante la variable item_number.</p>
<p><strong>Ejemplo de como procesar una Notificaci&oacute;n de Pago Instant&aacute;nea mediante PHP</strong></p>
<pre class="code php">&lt;?php

// Poner aqu&iacute; c&oacute;digo de inicializaci&oacute;n en base de datos //

if($_POST['payment_status']=='Completed' || $_POST['payment_status']=='Processed') {
	// Suponemos que el item_number que nosotros enviamos es del formato: XXXXX-YYYY
	// Donde XXXXX es el tipo de pago e YYYY es el identificador &uacute;nico del pago
	$tipo_venta_aux = explode('-',$_POST['item_number']);
	$tipo_venta = $tipo_venta_aux[0];
	$item_pagado = $tipo_venta_aux[1];

	$pago_valido = false;

        // Verificamos en base de datos
	switch($tipo_venta) {
		case 'VENTA':
			// Verificamos que es una venta existente y pendiente de pago
			$pago_valido = true;
			break;
		case 'ALQUILER':
			// Verificamos que es un alquiler existente y pendiente de pago
			$pago_valido = true;
			break;
		case 'PAGO_MENSUAL':
			// Verificamos que es un pago mensual existente y pendiente de pago
			$pago_valido = true;
			break;
	}

	if($pago_valido == true) {
		// Actualizamos el estado a pagado y hacemos lo que nos interese.
		// Como por ejemplo notificar al cliente de que el pago ha sido registrado.
	}
}

// Poner aqu&iacute; c&oacute;digo de finalizaci&oacute;n en base de datos //

?&gt;
</pre>
<h3><strong>P&aacute;ginas y art&iacute;culos relacionados</strong></h3>
<ul>
<li><a title="Pagar mediante PayPal en tu p&aacute;gina web" href="http://www.imaginanet.com/blog/como-utilizar-paypal-para-realizar-compras-en-tu-web.html">Como realizar compras en tu web mediante PayPal</a>.</li>
<li><a title="M&aacute;s informaci&oacute;n sobre PayPal IPN" href="https://www.paypal.com/ipn">Documentaci&oacute;n de PayPal sobre IPN</a>.</li>
<li><a title="Pagos masivos a PayPal" href="http://www.imaginanet.com/blog/pagos-en-serie-de-paypal.html">Pagos en serie a PayPal</a>.</li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=59</wfw:commentRss>
			<slash:comments>5</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/controlar-los-pagos-por-paypal-mediante-notificacion-de-pago-instantanea.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Programando para Android: una sencilla aplicación</title>
			<link>http://www.imaginanet.com/blog/programando-para-android-una-sencilla-aplicacion.html</link>
			<guid>http://www.imaginanet.com/blog/programando-para-android-una-sencilla-aplicacion.html</guid>
			<comments>http://www.imaginanet.com/blog/programando-para-android-una-sencilla-aplicacion.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Mon, 13 Dec 2010 10:40:12 +0100</pubDate>
					<category><![CDATA[Java]]></category>
					<category><![CDATA[Android]]></category>
					<description><![CDATA[Vamos a hablar sobre como programar una aplicaci&oacute;n para un dispositivo con Android que se va a tratar de una sencilla calculadora.
Como todos sabemos, Android se programa mediante el lenguaje de programaci&oacute;n Java. Este ejemplo de la calculadora puede parecer demasiado b&aacute;sico, pero con una idea inicial de como...]]></description>
			<content:encoded><![CDATA[><p>Vamos a hablar sobre como programar una aplicaci&oacute;n para un dispositivo con <strong>Android</strong> que se va a tratar de una sencilla calculadora.</p>
<p>Como todos sabemos, Android se programa mediante el lenguaje de programaci&oacute;n <strong>Java</strong>. Este ejemplo de la calculadora puede parecer demasiado b&aacute;sico, pero con una idea inicial de como hacer una peque&ntilde;a aplicaci&oacute;n para Android y nociones sobre Java, veremos que desarrollar un programa m&aacute;s complejo es muy f&aacute;cil.</p>
<p><span style="text-decoration: underline;">En primer lugar</span>, necesitaremos el <strong>Android SDK</strong> que lo podemos descargar de <a href="http://developer.android.com/sdk/index.html">http://developer.android.com/sdk/index.html</a></p>
<p>Tras instalarlo deberemos ejecutar el archivo android dentro de la carpeta tools y hacer lo siguiente:</p>
<ul>
<li>Instalar la plataforma de la versi&oacute;n Android a emular, lo haremos desde la pesta&ntilde;a <em>Available packages</em> y elegiremos la versi&oacute;n que queramos (2.1, 2.2, 2.3, etc)</li>
<li>Crear un dispositivo virtual, pesta&ntilde;a <em>Virtual devices</em>, que ser&aacute; nuestro dispositivo a emular.</li>
</ul>
<p><span style="text-decoration: underline;">Como segundo paso</span>, haremos uso de la plataforma <strong>Eclipse</strong> y su plugin ADT para el desarrollo de Android bajo Eclipse. Podemos hacerlo desde la direcci&oacute;n <a href="http://developer.android.com/sdk/eclipse-adt.html">http://developer.android.com/sdk/eclipse-adt.html</a></p>
<p>Ahora nos quedar&iacute;a configurar Eclipse para que supiera la ruta hasta el SDK de Android y tendr&iacute;amos todo preparado para trabajar. Lo podemos hacer desde el men&uacute; Window -&gt; Preferences y dentro de la ventana en la pesta&ntilde;a Android tenemos la opci&oacute;n SDK Location.</p>
<p>Ahora tenemos todo preparado y configurado para empezar a crear aplicaciones. La web del SDK de Android contiene varios ejemplo de como empezar a programar y el ejemplo m&aacute;s sencillo es el del "<em>Hola Mundo</em>" donde viene todo el proceso indicado arriba de forma m&aacute;s detallada (lo pod&eacute;is encontrar aqu&iacute; <a href="http://developer.android.com/resources/tutorials/hello-world.html">http://developer.android.com/resources/tutorials/hello-world.html</a>).</p>
<p>Nosotros nos vamos a basar en uno un poco m&aacute;s avanzado y lo vamos a ampliar hasta crear una aplicaci&oacute;n con cierta utilidad. Este ejemplo es el de como posicionar elementos con tama&ntilde;os y posiciones relativas <a href="http://developer.android.com/resources/tutorials/views/hello-relativelayout.html" target="_blank">http://developer.android.com/resources/tutorials/views/hello-relativelayout.html</a> y vamos a a&ntilde;adir algunos elementos y funcionalidades para crear nuestra sencilla calculadora.</p>
<h3>Creando nuestra primera aplicaci&oacute;n para Android</h3>
<p>Para ver cual queremos que sea la interfaz final e intuir el funcionamiento, vamos a mostrar una captura de pantalla del resultado final en el emulador:</p>
<p><img title="Primer programa para Android: una calculadora" src="http://www.imaginanet.com/ftp/articulos_web/android/Programa sencillo Android SDK.png" alt="Programaci&oacute;n para Android"/></p>
<p>donde podemos ver tres elementos: <em>TextView</em> (objeto para mostrar texto), <em>EditText</em> (caja de entrada de texto) y <em>Button</em> (bot&oacute;n).</p>
<p>Empezaremos creando en Eclipse un proyecto para Android, modificaremos el archivo <strong>res/layout/main.xml</strong> en su vista de c&oacute;digo de fuente y pegaremos el siguiente c&oacute;digo XML:</p>
<pre class="code">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"&gt;
    &lt;TextView
        android:id="@+id/label_a"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Operando A:"/&gt;
    &lt;EditText
        android:id="@+id/op_a"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@android:drawable/editbox_background"
        android:layout_below="@id/label_a"/&gt;
     &lt;TextView
        android:id="@+id/label_b"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/op_a"     
        android:text="Operando B:"/&gt;
    &lt;EditText
        android:id="@+id/op_b"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@android:drawable/editbox_background"
        android:layout_below="@id/label_b"/&gt;       
    &lt;Button
        android:id="@+id/sumar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/op_b"
        android:layout_alignParentLeft="true"
        android:layout_marginLeft="1dip"
		android:onClick="cSumar"        
        android:text="+" /&gt;
    &lt;Button
        android:id="@+id/restar"    
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/sumar"
        android:layout_alignTop="@id/sumar"
		android:onClick="cRestar"             
        android:text="-" /&gt;
    &lt;Button
        android:id="@+id/multiplicar"   
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/restar"
        android:layout_alignTop="@id/restar"
		android:onClick="cMultiplicar"            
        android:text="*" /&gt;
    &lt;Button
        android:id="@+id/dividir"    
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/multiplicar"
        android:layout_alignTop="@id/sumar"
 		android:onClick="cDividir" 
        android:text="/" /&gt;   
    &lt;TextView
        android:id="@+id/texto_resultado"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/dividir"                    
        android:text="Resultado:"/&gt;              
    &lt;TextView
        android:id="@+id/resultado"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/texto_resultado"          
        android:text="Realice operaci&oacute;n para obtener resultado"/&gt;                  
&lt;/RelativeLayout&gt;
</pre>
<p><span style="text-decoration: underline;">Los atributos relevantes para este ejemplo de cada elemento son</span>:</p>
<ul>
<li><em>android:id</em> identificador de cada objeto</li>
<li><em>android:layout_width</em> y <em>android:layout_height</em>, anchura y altura respectivamente</li>
<li><em>android:layout_below</em>: indica si el objeto est&aacute; debajo de otro</li>
<li><em>android:layout_toRightOf</em> y <em>android:layout_alignTop</em>: indican si est&aacute;n varios elementos en la misma fila sobre qu&eacute; objeto se coloca a su derecha y su posicionamiento en altura</li>
<li><em>android:text</em> es el texto por defecto en cada elemento</li>
<li><em>android:onClick</em> es el nombre del m&eacute;todo p&uacute;blico a ejecutar al pulsar ese bot&oacute;n. Este m&eacute;todo debe ser obligatoriamente p&uacute;blico y tener como par&aacute;metro de entrada la vista, ejemplo public void function cSumar(View view) { ... }.</li>
</ul>
<p>ahora vamos a programar el funcionamiento de los objetos descritos en el archivo de extensi&oacute;n java creado para el proyecto:</p>
<pre class="code php">package com.android.calculadora;

import android.app.Activity;
import android.os.Bundle;
import android.widget.*;
import android.view.*;

public class Calculadora extends Activity {
	
	// Instancias de objetos a usar
	private double valor_a, valor_b;
	private EditText op_a, op_b;
	private TextView resultado;
	
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        // Asignamos los objetos
        this.op_a = (EditText) findViewById(R.id.op_a);
        this.op_b = (EditText) findViewById(R.id.op_b);
        this.resultado = (TextView) findViewById(R.id.resultado);              
    }

    public void cSumar(View view) {
    	if(this.op_a.getText().toString().length() &gt; 0 &amp;&amp; this.op_b.getText().toString().length() &gt; 0) {
        	this.valor_a = Double.parseDouble(this.op_a.getText().toString());
        	this.valor_b = Double.parseDouble(this.op_b.getText().toString());    
        	this.resultado.setText(Double.toString((this.valor_a + this.valor_b)));    		
    	}
    }

    public void cRestar(View view) {
    	if(this.op_a.getText().toString().length() &gt; 0 &amp;&amp; this.op_b.getText().toString().length() &gt; 0) {
        	this.valor_a = Double.parseDouble(this.op_a.getText().toString());
        	this.valor_b = Double.parseDouble(this.op_b.getText().toString());    
        	this.resultado.setText(Double.toString((this.valor_a - this.valor_b)));    		
    	}
    }
    
    public void cMultiplicar(View view) {
    	if(this.op_a.getText().toString().length() &gt; 0 &amp;&amp; this.op_b.getText().toString().length() &gt; 0) {
        	this.valor_a = Double.parseDouble(this.op_a.getText().toString());
        	this.valor_b = Double.parseDouble(this.op_b.getText().toString());    
        	this.resultado.setText(Double.toString((this.valor_a * this.valor_b)));    		
    	}
    }
    
    public void cDividir(View view) {
    	if(this.op_a.getText().toString().length() &gt; 0 &amp;&amp; this.op_b.getText().toString().length() &gt; 0) {
        	this.valor_a = Double.parseDouble(this.op_a.getText().toString());
        	this.valor_b = Double.parseDouble(this.op_b.getText().toString());    
        	if(this.valor_b != 0) {
            	this.resultado.setText(Double.toString((this.valor_a / this.valor_b)));         		
        	}
        	else {
            	this.resultado.setText("Infinito");         		
        	}
    	}
    }       
}
</pre>
<p>El m&eacute;todo onCreate se ejecuta al crear la aplicaci&oacute;n y es donde asignamos los objetos declarados en el XML a objetos Java. Tras ello declaramos las funciones definidas en los atributos onClick de cada bot&oacute;n.</p>
<p>Por &uacute;ltimo nos quedar&iacute;a ejecutarlo y probar el funcionamiento.</p>
<h3>Conclusiones</h3>
<p>Como hemos dicho, este ejemplo de una calculadora es un ejemplo muy sencillo pero podemos ver que con un poco de c&oacute;digo y unas peque&ntilde;as nociones sobre Android SDK podemos sacar much&iacute;simo provecho de nuestros conocimientos sobre Java.</p>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=58</wfw:commentRss>
			<slash:comments>24</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/programando-para-android-una-sencilla-aplicacion.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Como usar HTML 5</title>
			<link>http://www.imaginanet.com/blog/como-usar-html-5.html</link>
			<guid>http://www.imaginanet.com/blog/como-usar-html-5.html</guid>
			<comments>http://www.imaginanet.com/blog/como-usar-html-5.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Mon,  6 Sep 2010 13:34:43 +0100</pubDate>
					<category><![CDATA[HTML5]]></category>
					<description><![CDATA[Antes de empezar habr&iacute;a que aclarar que HTML5 sigue en estado de borrador y lo seguir&aacute; estando durante algunos a&ntilde;os m&aacute;s.
Vamos a comentar las novedades m&aacute;s importantes.&nbsp;
Algo b&aacute;sico es que HTML5 est&aacute; definido en base al DOM (la representaci&oacute;n  interna de una web con la...]]></description>
			<content:encoded><![CDATA[><p>Antes de empezar habr&iacute;a que aclarar que HTML5 sigue en estado de borrador y lo seguir&aacute; estando durante algunos a&ntilde;os m&aacute;s.</p>
<p>Vamos a comentar las novedades m&aacute;s importantes.&nbsp;</p>
<p>Algo b&aacute;sico es que HTML5 est&aacute; definido en base al DOM (la representaci&oacute;n  interna de una web con la que trabaja un navegador), dejando de lado la  representaci&oacute;n &ldquo;real&rdquo;, definiendo a la vez un est&aacute;ndar HTML y XHTML.</p>
<p><span style="font-size: 15px; font-weight: bold;">Mejor estructura</span></p>
<p>Hoy en d&iacute;a se abusa bastante del elemento div, que nos permite  estructurar una web en bloques. En HTML5 hay varios elementos que sirven  para estructurar mejor una p&aacute;gina web, estableciendo qu&eacute; es cada  secci&oacute;n, y reemplazando en muchas ocasiones a div. Con este extra de  sem&aacute;ntica, ser&aacute; mucho m&aacute;s coherente y f&aacute;cil de entender por otras  personas. Y lo que es m&aacute;s importante, ser&aacute; trivial de entender para una  m&aacute;quina, d&aacute;ndole m&aacute;s importancia a unas secciones y pudiendo jugar con  esos datos autom&aacute;ticamente. Estos son los elementos:</p>
<ul>
<li><strong>section</strong> representa una secci&oacute;n &ldquo;general&rdquo; dentro de  un documento o aplicaci&oacute;n, como un cap&iacute;tulo de un libro. Puede contener  subsecciones y si lo acompa&ntilde;amos de h1-h6 podemos estructurar mejor toda  la p&aacute;gina.</li>
<li><strong>article</strong> representa un contenido independiente en un  documento, el caso m&aacute;s claro son las entradas de un blog o las noticias  de un peri&oacute;dico online. As&iacute;, dentro de la portada podremos tener varios  art&iacute;culos demarcados sem&aacute;nticamente, por lo que una herramienta puede  extraerlos f&aacute;cilmente.</li>
<li><strong>aside</strong> representa un contenido que est&aacute; muy poco  relacionado con el resto de la p&aacute;gina, como una barra lateral. Esencial  para delimitar el contenido &ldquo;importante&rdquo; del contenido &ldquo;de apoyo&rdquo;,  haciendo m&aacute;s caso al primero que al segundo.</li>
<li><strong>header</strong> representa la cabecera de una secci&oacute;n, y es  de suponer que se le d&eacute; m&aacute;s importancia que al resto, sobre todo si la  secci&oacute;n es un art&iacute;culo.</li>
<li><strong>footer</strong> representa el pi&eacute; de una secci&oacute;n, con  informaci&oacute;n acerca de la p&aacute;gina/secci&oacute;n que poco tiene que ver con el  contenido de la p&aacute;gina, como el autor, el copyright o el a&ntilde;o.</li>
<li><strong>nav</strong> representa una secci&oacute;n dedicada a la navegaci&oacute;n entre el sitio, como la t&iacute;pica barra superior de los peri&oacute;dicos.</li>
</ul>
<p>&nbsp;</p>
<p><span style="font-size: 15px; font-weight: bold;"><img src="http://www.imaginanet.com/ftp/articulos_web/html-html5.gif" alt="de Html a Html5" width="540" height="540" /><br /></span></p>
<p><span style="font-size: 15px; font-weight: bold;"><br />Mejores formularios</span></p>
<p>El elemento <strong>input</strong> ha sido ampliado y ahora permite todos estos tipos de datos:</p>
<ul>
<li><strong>datetime, datetime-local, date, month, week, time</strong>, para que indicar una fecha/hora. </li>
<li><strong>number</strong> para que el usuario indique un n&uacute;mero. </li>
<li><strong>range</strong> para indicar un rango entre dos n&uacute;meros. </li>
<li><strong>email</strong> para indicar un correo electr&oacute;nico. </li>
<li><strong>url</strong> para indicar una direcci&oacute;n web. </li>
<li><strong>search</strong> para indicar una b&uacute;squeda. </li>
<li><strong>color</strong> para indicar un color.</li>
</ul>
<p>Lo m&aacute;s interesante de esto es que los navegadores podr&aacute;n implementar  interfaces espec&iacute;ficas para cada tipo de dato, por ejemplo una fecha o  un color se podr&aacute;n indicar de manera directa e intuitiva. Otro ejemplo  ser&iacute;a el teclado del iPhone, que muestra unos s&iacute;mbolos u otros  dependiendo de si es un texto normal, un email (a&ntilde;ade @ y el punto) o  una url (a&ntilde;ade la barra y el punto com), y que por tanto gana mucho con  este est&aacute;ndar.</p>
<h2>Otros elementos importantes</h2>
<ul>
<li><strong>audio</strong> y <strong>video</strong> sirven para  incrustar un contenido multimedia de sonido o de v&iacute;deo, respectivamente.  Sin duda uno de los a&ntilde;adidos m&aacute;s interesantes, ya que permite  reproducir/controlar v&iacute;deos y audios sin necesidad de plugins como el de  Flash. Se tratan de manera totalmente nativa como cualquier otro  elemento, por ejemplo se pueden incluir enlaces o im&aacute;genes dentro de un  v&iacute;deo. Aunque las implementaciones actuales son un tanto ineficientes,  se espera que en un futuro pr&oacute;ximo se optimicen. Portales de v&iacute;deo como <a href="http://www.youtube.com/html5">Youtube</a> o <a href="http://openvideo.dailymotion.com/es">Dailymotion</a> ya est&aacute;n empezando a mostrar que un futuro sin Flash es posible (&iexcl;y necesario!).</li>
<li><strong>embed</strong> sirve para contenido incrustado pero no  nativo, sino ejecutado por plugins como el de Flash. Aunque embed est&aacute;  soportado por casi todos los navegadores desde hace tiempo, es ahora  cuando entra parte del est&aacute;ndar y evita el infierno/pelea entre object y  embed.</li>
<li><strong>canvas</strong> es un elemento complejo que permite generar  gr&aacute;ficos, dibujando elementos dentro de &eacute;l. Aunque nunca hayas o&iacute;do  hablar de &eacute;l, seguro que lo has usado alguna vez, por ejemplo de Google  Maps. Es un elemento muy potente que dar&aacute; bastante que hablar en el  futuro, y que ser&aacute; el culpable de aplicaciones web espectaculares.</li>
</ul>
<h2>M&aacute;s elementos</h2>
<ul>
<li><strong>dialog</strong> se plantea para escribir conversaciones, por ejemplo para transcripciones de chat.</li>
<li><strong>figure</strong> se plantea para asociar un contenido multimedia (una foto, un v&iacute;deo, etc) a un t&iacute;tulo o leyenda.</li>
<li><strong>mark</strong> representa un texto resaltado, por ejemplo para resaltar una b&uacute;squeda.</li>
<li><strong>meter</strong> representa una medida, como el n&uacute;mero de KB. Tiene m&aacute;s sentido si lo unimos con&hellip;</li>
<li><strong>progress</strong> representa el estado de una tarea, y se  puede usar por ejemplo al subir un documento o al realizar varias tareas  pesadas. Esto permitir&aacute; barras de tareas personalizadas y potentes.</li>
<li><strong>time</strong> representa una fecha o una hora.</li>
<li><strong>command</strong> representa un comando que el usuario puede ejecutar en su navegador.</li>
<li><strong>output</strong> representa una salida de un programa, probablemente ejecutado directamente en el navegador, como una calculadora.</li>
<li><strong>datagrid</strong> representa datos de manera interactiva y  permite trabajar din&aacute;micamente con informaci&oacute;n y cambiar la p&aacute;gina  respecto a esa informaci&oacute;n. Ser&aacute; &uacute;til sobre todo si se quiere trabajar  con aplicaciones que necesiten de bastantes datos a la vez en el lado  del cliente.</li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=57</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/como-usar-html-5.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Google Chrome cumple 2 años y trae nuevas funcionalidades</title>
			<link>http://www.imaginanet.com/blog/google-chrome-cumple-2-anos-y-trae-nuevas-funcionalidades.html</link>
			<guid>http://www.imaginanet.com/blog/google-chrome-cumple-2-anos-y-trae-nuevas-funcionalidades.html</guid>
			<comments>http://www.imaginanet.com/blog/google-chrome-cumple-2-anos-y-trae-nuevas-funcionalidades.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Mon,  6 Sep 2010 10:07:23 +0100</pubDate>
					<category><![CDATA[Google]]></category>
					<category><![CDATA[Navegadores]]></category>
					<description><![CDATA[Gogle Chrome est&aacute; en su mejor momento, habiendo alcanzado una cuota de mercado record del 7,5% durante el mes de agosto.
Por otra parte Google ya trabaja en nuevas funcionalidades para 'tablets' y 'netbooks'.
Entre las &uacute;ltimas revisiones de Chrome, hay&nbsp;dos nuevas actualizaciones: control de orientaci&oacute;n y...]]></description>
			<content:encoded><![CDATA[><p>Gogle Chrome est&aacute; en su mejor momento, <strong>habiendo alcanzado una cuota de mercado record del 7,5% durante el mes de agosto.</strong></p>
<p>Por otra parte Google ya trabaja en nuevas funcionalidades para 'tablets' y 'netbooks'.</p>
<p>Entre las &uacute;ltimas revisiones de Chrome, <em>hay</em>&nbsp;dos nuevas actualizaciones: control de orientaci&oacute;n y comandos de voz.</p>
<span>
<p>La primera de estas novedades en Chrome se antoja necesaria si tenemos en cuenta la proliferaci&oacute;n de 'tablets' y  'netbooks' en los &uacute;ltimos tiempos y, tambi&eacute;n, ante el lanzamiento (en  diciembre) de la versi&oacute;n de Chrome que Google desarrolla para estos dispositivos.</p>
<p>Ambas caracter&iacute;sticas ya estaban incluidas en el c&oacute;digo de Chromium,  pero el hecho de que est&eacute;n activadas por defecto hace pensar que pronto  estar&aacute;n disponibles en el navegador de Google.</p>
<p>Ante la importante actualizaci&oacute;n de sus grandes competidores: Firefox (con la llegada de la versi&oacute;n 4) e Internet Explorer (con su versi&oacute;n 9), Google sigue afinando y completando su sistema  operativo y no s&oacute;lo pensando en los equipos de sobremesa. De hecho, el  control de orientaci&oacute;n es algo obligado desde la proliferaci&oacute;n de  dispositivos m&oacute;viles como 'tablets' y 'netbooks'.</p>
<p><strong>Chrome&nbsp;contar&aacute; en su versi&oacute;n '7' con una aceleraci&oacute;n por hardware superior a Explorer 9 y Firefox 4</strong>, pero consumiendo m&aacute;s recursos que estos.</p>
</span>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=55</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/google-chrome-cumple-2-anos-y-trae-nuevas-funcionalidades.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Debate sobre plataformas móviles</title>
			<link>http://www.imaginanet.com/blog/debate-sobre-plataformas-moviles.html</link>
			<guid>http://www.imaginanet.com/blog/debate-sobre-plataformas-moviles.html</guid>
			<comments>http://www.imaginanet.com/blog/debate-sobre-plataformas-moviles.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Mon,  6 Sep 2010 12:30:29 +0100</pubDate>
					<category><![CDATA[Accesibilidad]]></category>
					<description><![CDATA[Representantes de los distintos sistemas operativos m&oacute;viles se  dieron cita en el evento Tendencias en Plataformas y Desarrollo M&oacute;vil,  organizado por Aecomo, para evaluar las posibilidades de cada uno en el  mercado y las tendencias futuras. El debate lo centraron iPhone y  Android.
Aecomo reuni&oacute; a...]]></description>
			<content:encoded><![CDATA[><p><strong>Representantes de los distintos sistemas operativos m&oacute;viles se  dieron cita en el evento Tendencias en Plataformas y Desarrollo M&oacute;vil,  organizado por Aecomo, para evaluar las posibilidades de cada uno en el  mercado y las tendencias futuras. El debate lo centraron iPhone y  Android.</strong></p>
<p><strong>Aecomo </strong>reuni&oacute; a desarrolladores y representantes de las empresas en el evento <strong>Tendencias en Plataformas y Desarrollo M&oacute;vil</strong>, para que&nbsp; expresaran sus puntos de vista sobre las posibilidades que ofrece el mercado.</p>
<p>El crecimiento experimentado por la programaci&oacute;n de aplicaciones  m&oacute;viles en los &uacute;ltimos tiempos ha sido vertiginoso y ha hecho que muchas  compa&ntilde;&iacute;as se sumen al negocio de construir su propia tienda o mercado.  Las conferencias dieron voz a los distintos actores presentes en el  mercado.</p>
<p><strong>Apple y sus buenas condiciones de trabajo</strong></p>
<p>El valedor de <strong>Apple </strong>fue <strong>Juan Antonio Mu&ntilde;oz-Gallego, socio fundador de Unkasoft</strong>, que justifica su trabajo sobre <strong>iPhone </strong>en la remuneraci&oacute;n econ&oacute;mica. Seg&uacute;n afirma el desarrollador, <strong>la compa&ntilde;&iacute;a paga un 70% de los beneficios que genere la aplicaci&oacute;n a su creador y lo hace en menos de treinta d&iacute;as</strong>.</p>
<div id="attachment_6905" class="wp-caption alignright">
<p class="wp-caption-text">Los smartphone pasan por ser el futuro de la telefon&iacute;a m&oacute;vil</p>
</div>
<p>La <strong>App Store</strong> <strong>ya ha obtenido 1.500 millones de descargas</strong>,  seg&uacute;n los datos de Mu&ntilde;oz-Gallego. Con esto pone de relevancia la  calidad del escaparate que Apple es capaz de ofrecer a los  programadores. Sin embargo, las apps m&oacute;viles m&aacute;s utilizadas son siempre  las mismas: <strong>Google Maps</strong>,<strong> Facebook</strong> y la herramienta musical <strong>Pandora</strong>.</p>
<p>En estos momentos, con el <strong>iPad </strong>ya  en la calle y arropado por un gran &eacute;xito en ventas, los desarrolladores  tienen la oportunidad o la obligaci&oacute;n, seg&uacute;n como se mire, de crear  aplicaciones duales, adaptadas a ambos dispositivos.</p>
<p>Mu&ntilde;oz-Gallego presenta la App Store de Apple como un buen escenario  para potenciar el comercio a trav&eacute;s del m&oacute;vil. Algunas compa&ntilde;&iacute;as ya han  aprovechado en este sentido las capacidades de las distintas versiones  del sistema operativo de iPhone, como <strong>Ikea, que lanz&oacute; un cat&aacute;logo virtual</strong>, permitiendo al usuario comprobar c&oacute;mo quedar&iacute;an sus productos en el lugar que vean con la c&aacute;mara del dispositivo.</p>
<p><strong>Android: innovaci&oacute;n m&aacute;s que dinero</strong></p>
<p>Tendencias en Plataformas y Desarrollo M&oacute;vil trajo a <strong>Israel Ferrer</strong>, <strong>desarrollador de Android y fundador del blog and.roid.es</strong>,  el m&aacute;s importante acerca de este sistema operativo en Espa&ntilde;a, que  ofreci&oacute; datos sobre el gran crecimiento del SO de Google en los &uacute;ltimos  meses.</p>
<p>Durante la charla, Ferrer profundiz&oacute; en la estrategia de Google, afirmando que <strong>al buscador le interesa principalmente la publicidad y el software para monopolizar este sector</strong>.  Por tanto, nada de terminales de momento. Para compensar, Android tiene  una larga lista de dispositivos que lo utilizan como sistema, por lo  que <strong>los desarrolladores deben ajustarse a distinto hardware, as&iacute; como diferentes tama&ntilde;os de pantalla y resoluciones</strong>.</p>
<p>Sin embargo, Android dispone de herramientas para solventar estas  dificultades, seg&uacute;n Ferrer, que aludi&oacute; a la versi&oacute;n 1.6 como una de las  m&aacute;s adecuadas para trabajar.</p>
<p>Respecto a las otra plataformas, Ferrer dijo: <strong>&ldquo;Google piensa que s&oacute;lo tiene dos competidores: iPhone y Blackberry&rdquo;</strong>.  Tambi&eacute;n hizo referencia a la posibilidad de convivencia de varias  tiendas de apps, como el Android Market, que permite la presencia de  otros competidores.</p>
<p>La confrontaci&oacute;n con Apple no se hizo esperar. En este punto, Israel Ferrer afirm&oacute;: &ldquo;<strong>La innovaci&oacute;n est&aacute; en Android&rdquo;</strong>, y se dirigi&oacute; a los desarrolladores diciendo que para ganar dinero &ldquo;iros a iPhone&rdquo;.</p>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=56</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/debate-sobre-plataformas-moviles.html</feedburner:origLink>
		</item>
				
		<item>
			<title>YouTube: Editor onLine de videos</title>
			<link>http://www.imaginanet.com/blog/youtube-editor-online-de-videos.html</link>
			<guid>http://www.imaginanet.com/blog/youtube-editor-online-de-videos.html</guid>
			<comments>http://www.imaginanet.com/blog/youtube-editor-online-de-videos.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Fri, 18 Jun 2010 10:16:24 +0100</pubDate>
					<category><![CDATA[Google Apps]]></category>
					<category><![CDATA[Google]]></category>
					<category><![CDATA[Web 2.0]]></category>
					<description><![CDATA[Cuando Apple acaba de anunciar una aplicaci&oacute;n para la edici&oacute;n onLine de videos, YouTube se ha adelantado y acaba de lanzar su editor de v&iacute;deo desde su web, as&iacute;, los usuarios ya no necesitan tener un programa de edici&oacute;n de v&iacute;deos que adem&aacute;s suele ser complicado de aprender a usar. El...]]></description>
			<content:encoded><![CDATA[>Cuando Apple acaba de anunciar una <a title="Ver post original" href="http://googleblog.blogspot.com/2010/06/edit-video-online-with-youtube-video.html" target="_blank">aplicaci&oacute;n para la edici&oacute;n onLine de videos</a>, YouTube se ha adelantado y acaba de lanzar su editor de v&iacute;deo desde su web, as&iacute;, los usuarios ya no necesitan tener un programa de edici&oacute;n de v&iacute;deos que adem&aacute;s suele ser complicado de aprender a usar. El editor online de YouTube es muy f&aacute;cil y sencillo de utilizar, y permite:<br />Crear un v&iacute;deo a partir de varios<br />Modificar el principio y fin del v&iacute;deo<br />Incluir m&uacute;sica en el v&iacute;deo desde AudioSwap<br />Despreocuparse de formatos cuando se crean v&iacute;deos nuevos.<br /><br />En <a title="Ver v&iacute;deo demo" href="http://www.youtube.com/watch?v=4YsQ6f125GY" target="_blank">este v&iacute;deo</a> se puede ver una demostraci&oacute;n de edici&oacute;n de un v&iacute;deo con esta aplicaci&oacute;n.<br /><br /><br />Google vs. Apple. &iexcl;Esto es competencia!]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=54</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/youtube-editor-online-de-videos.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Diseñando o re-diseñando tu página web a web 2.0</title>
			<link>http://www.imaginanet.com/blog/disenando-o-re-disenando-tu-pagina-web-a-web-20.html</link>
			<guid>http://www.imaginanet.com/blog/disenando-o-re-disenando-tu-pagina-web-a-web-20.html</guid>
			<comments>http://www.imaginanet.com/blog/disenando-o-re-disenando-tu-pagina-web-a-web-20.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Sat, 29 May 2010 10:21:30 +0100</pubDate>
					<category><![CDATA[Redes Sociales]]></category>
					<category><![CDATA[Marketing OnLine]]></category>
					<category><![CDATA[HTML5]]></category>
					<category><![CDATA[Accesibilidad]]></category>
					<category><![CDATA[Web 2.0]]></category>
					<description><![CDATA[&iquest;Has o&iacute;do hablar de web 2.0? Quien no! Est&aacute; de moda en internet hablar de web 2.0, aunque mucha gente no sabe muy bien lo qu&eacute; es.Todo el mundo habla sobre Web 2.0, pero mucha gente puede pensar que es una estrategia de marketing y un t&eacute;rmino cada vez m&aacute;s utilizado y est&aacute; siendo...]]></description>
			<content:encoded><![CDATA[><strong>&iquest;Has o&iacute;do hablar de web 2.0? </strong>Quien no! Est&aacute; de moda en internet hablar de web 2.0, aunque mucha gente no sabe muy bien lo qu&eacute; es.<br />Todo el mundo habla sobre Web 2.0, pero mucha gente puede pensar que es una estrategia de marketing y un t&eacute;rmino cada vez m&aacute;s utilizado y est&aacute; siendo sobre-utilizado.<br /><br />A pesar de todo lo que se est&aacute; hablando, hay otro cap&iacute;tulo sobre web 2.0, que al margen de la publicidad que se le est&aacute; dando y todo el marketing que rodea el t&eacute;rmino, es mucho m&aacute;s potente que todo eso.<br /><br />El concepto <strong>Web 2.0</strong> comenz&oacute; en una sesi&oacute;n de tormenta de ideas (brainstorming) que se llev&oacute; a cabo entre O'Reilly y MediaLive Int. En ella, analizaron las empresas web que hab&iacute;an sobrevivido a la quiebra que hubo de las punto com. En la sesi&oacute;n, analizaron a las empresas que hab&iacute;an sobrevivido a este breakdown. La conclusi&oacute;n que obtuvieron fue bastante interesante, la mayor&iacute;a de estas empresas ten&iacute;an muy pocas cosas en com&uacute;n. &iquest;Hab&iacute;a alguna conexi&oacute;n entre ellas? &iquest;Era esa quiebra un punto de inflexi&oacute;n para la web? O'Reilly y MediaLive cre&iacute;an que s&iacute;. Y entonces se les ocurri&oacute; el t&eacute;rmino Web 2.0<br /><br /><strong>Entonces, &iquest;Qu&eacute; es Web 2.0?</strong><br />En la wikipedia lo definen como una serie de servicios disponibles en internet de segunda generaci&oacute;n que permite la colaboraci&oacute;n entre los usuarios y compartir informaci&oacute;n online. Al contrario que la web de primera generaci&oacute;n, Web 2.0 le da al usuario una experiencia mucho m&aacute;s parecida a la de una aplicaci&oacute;n o programa de escritorio, que a la p&aacute;gina web est&aacute;tica t&iacute;pica de hace a&ntilde;os. Las aplicaciones o webs Web 2.0, suelen utilizar tecnolog&iacute;as o t&eacute;cnicas de programaci&oacute;n que aparecieron a final de los 90, web services APIs (1998), Ajax (1998) y web syndication (1997). Permiten con frecuencia el env&iacute;o masivo de mensajes a sectores o perfiles de usuarios (web social applications). El concepto en s&iacute;, puede englobar el concepto de "blogs" y de "wikis".<br /><br />No existe ninguna definici&oacute;n oficial que defina lo qu&eacute; es "Web 2.0", pero s&iacute; que hay una serie de cosas que todos los que utilizan este emblema tienen en com&uacute;n. Puedes visitar Flickr, del.icious, Wikipedia, Amazon (reviews - opiniones), y el sistema de reputaci&oacute;n de eBay, son sitios conocidos que nacieron con la web 2.0<br /><br />Web 2.0 es algo constru&iacute;do sobre un conocimiento colectivo. Proporciona una herramienta social aplicada a la web, dando m&aacute;s herramientas y conocimiento al usuario y d&aacute;ndoles la oportunidad de poder opinar libremente. Adem&aacute;s, hay que fijarse en que cada vez aparecen m&aacute;s aplicaciones web como hojas de c&aacute;lculo, procesadores de texto, listas de tareas, alertas, calendarios, p&aacute;ginas personales, blogs, comunidades, redes sociales, etc.<br /><br />Adem&aacute;s, la web 2.0 no utiliza la maquetaci&oacute;n cuadriculada de las tablas y sus renderizados. Los dise&ntilde;os web 2.0 han cambiado de las t&iacute;picas cajas cuadriculadas a la flexibilidad de las curvas, dise&ntilde;ar para la web de hoy permite dise&ntilde;os curvos y con movimiento, textos bonitos, gradientes, efectos chulis que parecen flash, y colores bonitos y agradables.<br /><br /><em>Esquinas redondeadas</em><br />Antes era bastante necesario el uso de cajas cuadriculadas, la web 2.0 ha aportado las esquinas redondeadas como algo b&aacute;sico y simple de realizar. Con la web anterior, crear una caja con esquinas redondeadas era una odisea de recorte de im&aacute;genes y posicionado de estas y no era tareal trivial.<br /><br /><em>Titulares que funcionan</em><br />La web 2.0 ha estandarizado el uso de titulares para resaltar los textos de importancia.<br /><br /><em>Gradientes</em><br />Oto elemento de dise&ntilde;o bastante usado en web 2.0 son los gradientes. Sobre todo es util en fondos, por ejemplo podemos tener un gradiente en la cabecera que acabe en un color utilizado como fondo de toda la p&aacute;gina web (ejemplo: http://www.photoshoplab.com/web20-design-kit.html)<br /><br />Y otras propiedades de dise&ntilde;o como <em>colores luminosos, pesta&ntilde;as, reflejos, efectos de movimiento, botones, iconos, y cajas de texto claras para el env&iacute;o de formularios</em>. Otro elemento que se utiliza mucho son las <em>nubes de tags</em>, en los &uacute;ltimos 6 meses se est&aacute;n poniendo de moda. Sitios que las usan son del.icio.us, Technorati, Flickr, ... Una nube de tags te da una idea abstracta de los temas que encontrar&aacute;s en un website, donde lo m&aacute;s popular, aparece a tama&ntilde;o mayor. Una nube de tags (tambi&eacute;n conocida como folkloromies), adem&aacute;s de ser algo moderno y de moda, le da al usuario una herramienta de b&uacute;squeda de contenidos muy f&aacute;cil, r&aacute;pida e intuitiva.<br /><br />Aunque hemos enumerado varias cosas de web 2.0, esta no es una tecnolog&iacute;a, tampoco es una nueva t&eacute;cnica de dise&ntilde;o, lo que realmente es una transici&oacute;n de la web, una transici&oacute;n hacia la experiencia de usuario, la web est&aacute; hecha para el usuario, y para ello utiliza t&eacute;cnicas de dise&ntilde;o y programaci&oacute;n soportadas desde finales de los 90.<br /><br />Tu web puede ser algo m&aacute;s que un lugar informativo. Tu presencia en la web es un lugar m&aacute;s, que con las t&eacute;cnicas de programaci&oacute;n adecuadas puedes montar todo un mundo alrededor de tu negocio<br /><br />En Imaginanet ofrecemos servicios de programaci&oacute;n y dise&ntilde;o web 2.0, si te interesa, visita nuestra secci&oacute;n de <a title="Qu&eacute; te ofrecemos de dise&ntilde;o web 2.0" href="/diseno-web.html">dise&ntilde;o web 2.0</a> para conocer qu&eacute; podemos ofrecerte en cuanto a dise&ntilde;o, o la de programaci&oacute;n web 2.0 si te interesa un desarrollo bien hecho.<br /><br /><br />]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=53</wfw:commentRss>
			<slash:comments>1</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/disenando-o-re-disenando-tu-pagina-web-a-web-20.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Google y Twitter hacen pública su política publicitaria</title>
			<link>http://www.imaginanet.com/blog/google-y-twitter-hacen-publica-su-politica-publicitaria.html</link>
			<guid>http://www.imaginanet.com/blog/google-y-twitter-hacen-publica-su-politica-publicitaria.html</guid>
			<comments>http://www.imaginanet.com/blog/google-y-twitter-hacen-publica-su-politica-publicitaria.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Fri, 28 May 2010 23:34:28 +0100</pubDate>
					<category><![CDATA[Redes Sociales]]></category>
					<category><![CDATA[Marketing OnLine]]></category>
					<category><![CDATA[Google]]></category>
					<description><![CDATA[En la misma semana, estas dos empresas de internet han hecho p&uacute;blica su pol&iacute;tica publicitaria&nbsp;online.Google en su blog hace p&uacute;blico por primera vez, las comisiones que reciben los due&ntilde;os de websites con AdSense. El 68% de los ingresos generados se entregan a los propietarios de websites.Twitter por...]]></description>
			<content:encoded><![CDATA[><p>En la misma semana, estas dos empresas de internet han hecho p&uacute;blica su pol&iacute;tica publicitaria&nbsp;online.<br /><br />Google en su blog hace p&uacute;blico por primera vez, las comisiones que reciben los due&ntilde;os de websites con AdSense. El 68% de los ingresos generados se entregan a los propietarios de websites.<br /><br />Twitter por otra parte ha anunciado que controlar&aacute; m&aacute;s la publicidad e impedir&aacute; que terceros vendan tweets publicitarios gestionados por Twitter, seg&uacute;n anuncian "no permitir&aacute;n inyectar mensajes remunerados en flujos de mensajes de su red social". Toman esta medida por el engorro que puede suponer el aumento descontrolado de publicidad mal gestionada.&nbsp;</p>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=50</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/google-y-twitter-hacen-publica-su-politica-publicitaria.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Datos de usuarios de Twitter</title>
			<link>http://www.imaginanet.com/blog/datos-de-usuarios-de-twitter.html</link>
			<guid>http://www.imaginanet.com/blog/datos-de-usuarios-de-twitter.html</guid>
			<comments>http://www.imaginanet.com/blog/datos-de-usuarios-de-twitter.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Sat, 29 May 2010 00:06:40 +0100</pubDate>
					<category><![CDATA[Redes Sociales]]></category>
					<category><![CDATA[Marketing OnLine]]></category>
					<description><![CDATA[Las cifras de uso de Twitter a nivel mundial, o en ingl&eacute;s, son impresionantes. No lo son tanto en espa&ntilde;ol.Hoy existen 106 millones de usuarios, que env&iacute;an 55 millones de tweets al dia. Sale a 640 tweets por segundo.Diariamente, se captan 300.000 usuarios nuevos. Y diariamente acceden 180 millones de visitantes...]]></description>
			<content:encoded><![CDATA[>Las cifras de uso de Twitter a nivel mundial, o en ingl&eacute;s, son impresionantes. No lo son tanto en espa&ntilde;ol.<br /><br />Hoy existen 106 millones de usuarios, que env&iacute;an 55 millones de tweets al dia. Sale a 640 tweets por segundo.<br />Diariamente, se captan 300.000 usuarios nuevos. Y diariamente acceden 180 millones de visitantes &uacute;nicos.<br /><br />Hay que tener en cuenta que los mensajes (tweets) se encuentran limitados a 140 caracteres. Los tweets tiene que ser muy cortos y condensados. Cuando hablamos de caracteres hay que contar letras, signos de puntuaci&oacute;n y espacios.<br /><br />El Instituto Max Planck de Alemania, hizo un examen de la actividad en Twitter de una muestra aleatoria de 300.000 usuarios para investigar c&oacute;mo los usuarios usan el servicio, ya que se sabe que el servicio llama mucho la atenci&oacute;n de medios y celebridades, pero no se saben sus efectos &iquest;lo usan los amigos para comunicarse? &iquest;se usa como medio de expresi&oacute;n libre? &iquest;herramienta de marketing online?<br /><br />Los resultados sugieren que el n&uacute;mero de seguidores no tiene relaci&oacute;n con lo que se influye sobre ellos. Es decir, parece no muy rentable el dinero que pagan algunas empresas por conseguir seguidores. El tener muchos seguidores en Twitter significa muy poco. As&iacute; que el presidente de Venezuela que busca el mill&oacute;n de seguidores, tendr&aacute; poca influencia sobre ellos.<br /><br />Existe poca interactividad. Se debe poner m&aacute;s &eacute;nfasis en aumentar la capacidad de respuesta de la audiencia en los Twitter. Hay mucha comunicaci&oacute;n de una &uacute;nica v&iacute;a. Aunque tambi&eacute;n se expone que las empresas que publican noticias han encontrado un gran aliado en Twitter para enlazar a sus noticias comentarios o tweets.<br /><br />Existen pocos twitters activos realmente. &nbsp;Se usa mucho para buscar y leer mensajes de otros, pero poco para generar nuevos. S&oacute;lo el 3% de los twitters tienen m&aacute;s de 100 seguidores. El 24% de los twitters tiene 0 seguidores.<br /><br />Por sexos, un 45% son hombres y el 55% mujeres, aunque los hombres tienen un 15% m&aacute;s seguidores que ellas.<br /><br />El lenguaje m&aacute;s usado es el ingl&eacute;s, el 61% de los usuarios son de habla inglesa, y s&oacute;lo el 4% son en idioma espa&ntilde;ol.<br />Pa&iacute;ses desde donde m&aacute;s se usa: USA el 33%, seguido de India, Alemania, Jap&oacute;n y Reino Unido. De latinoam&eacute;rica es muy popular en Brasil.<br /><br /><br /><br />&nbsp;]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=52</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/datos-de-usuarios-de-twitter.html</feedburner:origLink>
		</item>
				
		<item>
			<title>FaceBook llega a los 10 millones de usuarios en España</title>
			<link>http://www.imaginanet.com/blog/facebook-llega-a-los-10-millones-de-usuarios-en-espana.html</link>
			<guid>http://www.imaginanet.com/blog/facebook-llega-a-los-10-millones-de-usuarios-en-espana.html</guid>
			<comments>http://www.imaginanet.com/blog/facebook-llega-a-los-10-millones-de-usuarios-en-espana.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Fri, 28 May 2010 23:45:19 +0100</pubDate>
					<category><![CDATA[Redes Sociales]]></category>
					<category><![CDATA[Marketing OnLine]]></category>
					<description><![CDATA[FaceBook ha hecho p&uacute;blico que sobrepasa los 10 millones de usuarios en Espa&ntilde;a, usuarios registrados y que acceden a su cuenta con frecuencia.FaceBook naci&oacute; en 2004, y a d&iacute;a de hoy, una cuarta parte de la poblaci&oacute;n espa&ntilde;ola est&aacute; registrada en FaceBook, y el 70% de estos, se conecta...]]></description>
			<content:encoded><![CDATA[>FaceBook ha hecho p&uacute;blico que sobrepasa los 10 millones de usuarios en Espa&ntilde;a, usuarios registrados y que acceden a su cuenta con frecuencia.<br /><br />FaceBook naci&oacute; en 2004, y a d&iacute;a de hoy, una cuarta parte de la poblaci&oacute;n espa&ntilde;ola est&aacute; registrada en FaceBook, y el 70% de estos, se conecta todos los d&iacute;as. As&iacute; Espa&ntilde;a se pone en la d&eacute;cima plaza a nivel muncial en n&uacute;mero de usuarios activos.&nbsp;<br /><br />Si a esto se a&ntilde;ade que FaceBook tiene 62'3 millones de usuarios en espa&ntilde;ol a nivel mundial, lo convierte en una red para la difusi&oacute;n de mensajes muy atractiva en nuestro idioma.&nbsp;]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=51</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/facebook-llega-a-los-10-millones-de-usuarios-en-espana.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Internet TV. Alianza de Google con Sony  e Intel.</title>
			<link>http://www.imaginanet.com/blog/internet-tv-alianza-de-google-con-sony-e-intel.html</link>
			<guid>http://www.imaginanet.com/blog/internet-tv-alianza-de-google-con-sony-e-intel.html</guid>
			<comments>http://www.imaginanet.com/blog/internet-tv-alianza-de-google-con-sony-e-intel.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Tue, 18 May 2010 13:08:13 +0100</pubDate>
					<category><![CDATA[Internet]]></category>
					<category><![CDATA[Google Apps]]></category>
					<category><![CDATA[Google]]></category>
					<description><![CDATA[Seg&uacute;n una encuesta realizada por Intel a nivel mundial, el electrodom&eacute;stico que m&aacute;s desear&iacute;an tener los ciudadanos es un cable que conecte internet con su televisor. El mi&eacute;rcoles 19 de mayo Google lo presenta en San Francisco. Si algui&eacute;n piensa que la TDT ha tra&iacute;do lo m&aacute;s...]]></description>
			<content:encoded><![CDATA[>Seg&uacute;n una encuesta realizada por Intel a nivel mundial, el electrodom&eacute;stico que m&aacute;s desear&iacute;an tener los ciudadanos es un cable que conecte internet con su televisor. El mi&eacute;rcoles 19 de mayo Google lo presenta en San Francisco. Si algui&eacute;n piensa que la TDT ha tra&iacute;do lo m&aacute;s moderno, la TDT ha sido un adelanto, el futuro est&aacute; en un sistema abierto que ha desarrollado Google que instala internet dentro del televisor y dentro del mismo mando a distancia. Sea cual sea el modelo y marca de estos.<br /><br />Intel ha proporcionado los chips y las televisiones con las que se ha desarrollado son de Sony, aunque se prevee que se pueda instalar en todas las marcas del sector. No se sabe todav&iacute;a si GoogleTV o SmartTV proporcionar&aacute; acceso a todo internet o s&oacute;lo a sus webs como YouTube, Gmail, Picasa, Chrome, Buzz, ...<br /><br />Hace un a&ntilde;o que se venden televisiones con programas que incluyen servicios de Yahoo! como el tiempo o la bolsa. El objetivo de Google es inclu&iacute;r internet en el televisor, y si lo logra "La televisi&oacute;n como concepto va a desaparecer; quedar&aacute; el televisor aunque al fin y al cabo es una pantalla".<br /><br />Siempre se ha dicho que el ordenador nunca ganar&iacute;a al televisor, porque el sof&aacute; es m&aacute;s c&oacute;modo que la silla, pero parece que todo llega. Ahora hay que hacer apuestas por el mando del televisor, y el que tiene todos los boletos es el tel&eacute;fono m&oacute;vil. La aplicaci&oacute;n m&aacute;s descargada en Espa&ntilde;a para iPhone es para ver la televisi&oacute;n de catalu&ntilde;a en directo.<br /><br />La competencia en la TV tiene dos nuevos competidores a nivel mundial: Apple y Google.]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=49</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/internet-tv-alianza-de-google-con-sony-e-intel.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Rediseño web 2.0 para dispositivos móviles táctiles</title>
			<link>http://www.imaginanet.com/blog/rediseno-web-20-para-dispositivos-moviles-tactiles.html</link>
			<guid>http://www.imaginanet.com/blog/rediseno-web-20-para-dispositivos-moviles-tactiles.html</guid>
			<comments>http://www.imaginanet.com/blog/rediseno-web-20-para-dispositivos-moviles-tactiles.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Tue, 18 May 2010 12:49:05 +0100</pubDate>
					<category><![CDATA[Internet]]></category>
					<category><![CDATA[HTML5]]></category>
					<category><![CDATA[Accesibilidad]]></category>
					<category><![CDATA[Web 2.0]]></category>
					<description><![CDATA[Desde el lanzamiento del iPhone, y reforzado por el nuevo iPad, los fabricantes de dispositivos m&oacute;viles se han inclinado por las pantallas t&aacute;ctiles (multitouch interfaces) y ahora parece llegar a los dispositivos de escritorio como el iPad. Este nuevo entorno de navegaci&oacute;n, hace que el dise&ntilde;o web se...]]></description>
			<content:encoded><![CDATA[>Desde el lanzamiento del iPhone, y reforzado por el nuevo iPad, los fabricantes de dispositivos m&oacute;viles se han inclinado por las pantallas t&aacute;ctiles (multitouch interfaces) y ahora parece llegar a los dispositivos de escritorio como el iPad. Este nuevo entorno de navegaci&oacute;n, hace que el dise&ntilde;o web se piense tambi&eacute;n para estos dispositivos, ya que aunque no lo parezca, la revoluci&oacute;n est&aacute; aqu&iacute;.<br /><br />Steve Jobs dijo que Flash no sirve para los dispositivos t&aacute;ctiles, hay otras facetas de la web que hay que modificar para poder dar un buen soporte a este tipo de aparatos.<br />Raju Vegesna, comenta que estos dispositivos est&aacute;n pidiendo un cambio en la forma de usar los ordenadores, llevamos 20 a&ntilde;os con la misma interface. Los men&uacute;s desplegables son muy f&aacute;ciles de usar en dispositivos tradicionales pero no pasa lo mismo con las pantallas t&aacute;ctiles. Distintos toques en la pantalla t&aacute;ctil no se reconocen com debieran, ya que los servicios web actuales, la mayor&iacute;a de ellos, no est&aacute;n concebidos para la navegaci&oacute;n t&aacute;ctil.<br /><br />As&iacute;, surge una necesidad bastante aconsejable: las aplicaciones web y servicios web se tienen que redise&ntilde;ar para adaptarse tambi&eacute;n a esta forma de navegaci&oacute;n, o deben crearse formas alternativas de navegaci&oacute;n pensadas para estos dispositivos.<br /><br /><a href="http://www.technologyreview.com/computing/25236/?nlid=2950&amp;a=f" target="_blank">Ver noticia original en ingl&eacute;s</a>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=48</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/rediseno-web-20-para-dispositivos-moviles-tactiles.html</feedburner:origLink>
		</item>
				
		<item>
			<title>El número de usuarios de Internet en España sigue aumentando</title>
			<link>http://www.imaginanet.com/blog/el-numero-de-usuarios-de-internet-en-espana-sigue-aumentando.html</link>
			<guid>http://www.imaginanet.com/blog/el-numero-de-usuarios-de-internet-en-espana-sigue-aumentando.html</guid>
			<comments>http://www.imaginanet.com/blog/el-numero-de-usuarios-de-internet-en-espana-sigue-aumentando.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Mon, 17 May 2010 18:04:25 +0100</pubDate>
					<category><![CDATA[Internet]]></category>
					<category><![CDATA[Redes Sociales]]></category>
					<category><![CDATA[Marketing OnLine]]></category>
					<description><![CDATA[Seg&uacute;n un estudio de Internet World Stats, Espa&ntilde;a es el sexto usuario de internet en Europa y el d&eacute;cimo cuarto puesto a nivel mundial. Las comunidades donde m&aacute;s usuarios existen son Madrid, Catalu&ntilde;a y Pa&iacute;s Vasco, mientras que Murcia y Extremadura son las que menos usuarios tienen.El...]]></description>
			<content:encoded><![CDATA[><p>Seg&uacute;n un estudio de Internet World Stats, Espa&ntilde;a es el sexto usuario de internet en Europa y el d&eacute;cimo cuarto puesto a nivel mundial. Las comunidades donde m&aacute;s usuarios existen son Madrid, Catalu&ntilde;a y Pa&iacute;s Vasco, mientras que Murcia y Extremadura son las que menos usuarios tienen.<br /><br />El &iacute;ndice de penetraci&oacute;n de internet en la poblaci&oacute;n espa&ntilde;ola es del 72% (en el ranking mundial el puesto ocupado ser&iacute;a el 20) y tiene un crecimiento medio del 440% desde el a&ntilde;o 2000.<br /><br />En el ranking de uso de redes sociales, Espa&ntilde;a ocupa el s&eacute;ptimo puesto a nivel mundial, el 80% de los usuarios est&aacute; en una red social y el 60% consulta estas todos los d&iacute;as.&nbsp;<br /><br />En el informe se recoge que los &iacute;ndices de penetraci&oacute;n a destacar son: Madrid (58%), Catalu&ntilde;a (57%) y Pa&iacute;s Vasco (55%). Mientras que las comunidades con menor &iacute;ndice son Murcia (39%) y Extremadura (36%), estas dos &uacute;ltimas seg&uacute;n el informe, son las que menor crecimiento han tenido en los &uacute;ltimos a&ntilde;os.<br /><br /><strong>Perfil de usuario de internet en Espa&ntilde;a</strong><br />Un 55% son hombres y un 45% mujeres. Una cuarta parte est&aacute; entre los 14 y 24 a&ntilde;os, otra entre 25 y 34 a&ntilde;os, otra entre 35 y 44 a&ntilde;os y el &uacute;ltimo grupo es de m&aacute;s de 45 a&ntilde;os. El perfil de usuario que m&aacute;s ha crecido es el de m&aacute;s de 55 a&ntilde;os.<br />Adem&aacute;s, se informa de que el perfil social del usuario de la web es m&aacute;s alto que el de la poblaci&oacute;n general.<br /><br /><strong>Las redes sociales m&aacute;s populares en Espa&ntilde;a: FaceBook, Tuenti y Twitter.</strong><br />FaceBook con 7.900.000 usuarios es la m&aacute;s importante, seguida de Tuenti con 7 millones y Twitter. En el informe se comenta que las empresas que utilizan redes sociales superan en beneficios e ingresos a la competencia.<br /><br />Si a esto le a&ntilde;adimos que un 30% de los usuarios que utiliza redes sociales recuerda la publicidad de estas, el 52% se convierte en fan de una marca y el 46% habla bien de una marca.&nbsp;</p>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=47</wfw:commentRss>
			<slash:comments>2</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/el-numero-de-usuarios-de-internet-en-espana-sigue-aumentando.html</feedburner:origLink>
		</item>
				
		<item>
			<title>GobolNet, la red social de los municipios españoles</title>
			<link>http://www.imaginanet.com/blog/gobolnet-la-red-social-de-los-municipios-espanoles.html</link>
			<guid>http://www.imaginanet.com/blog/gobolnet-la-red-social-de-los-municipios-espanoles.html</guid>
			<comments>http://www.imaginanet.com/blog/gobolnet-la-red-social-de-los-municipios-espanoles.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Mon, 17 May 2010 17:50:54 +0100</pubDate>
					<category><![CDATA[Internet]]></category>
					<category><![CDATA[Redes Sociales]]></category>
					<category><![CDATA[Marketing OnLine]]></category>
					<description><![CDATA[La FEMP (Federaci&oacute;n Espa&ntilde;ola de Municipios y Provincias) acaba de lanzar GOBOLnet, la red social lanzada con el objetivo de ser un canal de comunicaci&oacute;n cont&iacute;nuo con los cargos pol&iacute;ticos, t&eacute;cnicos y cualquier trabajador de las entidades locales con los ciudadanos. Desde esta red social se...]]></description>
			<content:encoded><![CDATA[>La FEMP (Federaci&oacute;n Espa&ntilde;ola de Municipios y Provincias) acaba de lanzar GOBOLnet, la red social lanzada con el objetivo de ser un canal de comunicaci&oacute;n cont&iacute;nuo con los cargos pol&iacute;ticos, t&eacute;cnicos y cualquier trabajador de las entidades locales con los ciudadanos. Desde esta red social se podr&aacute;n realizar adem&aacute;s video conferencias, intercambiar documentos, enviar mensajes masivos a toda la red GobolNet, etc.<br /><br />Esta experiencia, es un proyecto pionero a nivel mundial ya que aporta nuevos conceptos a las redes sociales.&nbsp;]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=46</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/gobolnet-la-red-social-de-los-municipios-espanoles.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Pagos en serie de PayPal</title>
			<link>http://www.imaginanet.com/blog/pagos-en-serie-de-paypal.html</link>
			<guid>http://www.imaginanet.com/blog/pagos-en-serie-de-paypal.html</guid>
			<comments>http://www.imaginanet.com/blog/pagos-en-serie-de-paypal.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Fri, 14 May 2010 13:25:40 +0100</pubDate>
					<category><![CDATA[Comercio electrónico]]></category>
					<category><![CDATA[PHP]]></category>
					<description><![CDATA[Los pagos en serie de PayPal (batch payments) sirven para realizar m&uacute;ltiples pagos de forma masiva a personas que tengan una cuenta de PayPal para realizar pagos masivos o transferencias peri&oacute;dicas de dinero que es necesario para ciertas empresas o tiendas en Internet.
La gran ventaja es que podemos programar una...]]></description>
			<content:encoded><![CDATA[><p>Los pagos en serie de PayPal (<em>batch payments</em>) sirven para realizar m&uacute;ltiples pagos de forma masiva a personas que tengan una cuenta de PayPal para <span style="text-decoration: underline;">realizar pagos masivos o transferencias peri&oacute;dicas de dinero</span> que es necesario para ciertas <a title="Tiendas, negocios y empresas virtuales" href="http://www.imaginanet.com/diseno-web/tiendas-virtuales.html">empresas o tiendas en Internet</a>.</p>
<p>La gran ventaja es que podemos programar una aplicaci&oacute;n que realice este pago a los usuarios que nosotros deseemos. Para ello deberemos crear un fichero en el que los datos de cada pago estar&aacute;n separados por tabulaciones y cada pago por un salgo de l&iacute;nea. El formato de cada pago es el siguiente:</p>
<ol>
<li><strong>Direcci&oacute;n de correo electr&oacute;nico</strong> del usuario</li>
<li><strong>Importe</strong> en el formato 12.34</li>
<li><strong>C&oacute;digo de la moneda</strong> de pago (<a href="https://www.paypal.com/es/cgi-bin/webscr?cmd=_batch-payment-format-outside">monedas de pago en PayPal</a>). En cada archivo s&oacute;lo puede haber una moneda, por lo que si tenemos que hacer varios pagos de varias monedas deberemos generar diferentes archivos</li>
<li><strong>Identificador</strong> del pago (sin espacios)</li>
<li><strong>Texto explicativo</strong> del pago (opcional)</li>
</ol>
<p>Un ejemplo de archivo de pago en serie ser&iacute;a el siguiente:</p>
<pre class="code">123456@dompruebas.es	2.43	EUR	transferencia_2245	Pago del d&iacute;a  14 de Mayo
abcdfeg@dompruebas.es	122.53	EUR	transferencia_2246	Pago del d&iacute;a  14 de Mayo
</pre>
<p>&nbsp;</p>
<h3>Ejemplo de generaci&oacute;n de pago en serie en PHP</h3>
<p>Con el siguiente sencillo ejemplo, conseguiremos hacer un script que realice pagos en serie. La fuente la suponemos de una base de datos, y tras crear el archivo, deberemos subir el archivo a la web de PayPal para realizar los pagos:</p>
<pre class="code php">&lt;?php
&nbsp;
// Resultados obtenidos de una base de datos, XML, etc.
$moneda = "EUR";
&nbsp;
$bp[0]['email'] = "123456@dompruebas.es";
$bp[0]['importe'] = "2.43";
$bp[0]['identificador'] = "transferencia_2245";
$bp[0]['mensaje'] = "Pago del d&iacute;a  14 de Mayo";
&nbsp;
$bp[1]['email'] = "abcdfeg@dompruebas.es";
$bp[1]['importe'] = "122.53";
$bp[1]['identificador'] = "transferencia_2246";
$bp[1]['mensaje'] = "Pago del d&iacute;a  14 de Mayo";
&nbsp;
// Procesamos
$archivo = "";
$icount = count($bp);
for($i=0;$i&lt;$icount;$i++) {
   $archivo.=$bp[$i]['email']."\t";
   $archivo.=$bp[$i]['importe']."\t";
   $archivo.=$moneda."\t";
   $archivo.=$bp[$i]['identificador']."\t";
   $archivo.=$bp[$i]['mensaje']."\r\n";
}
&nbsp;
$nombre_archivo = date("Ymd").'_'.$moneda.'_bp_'.time().'.txt';
$fd=fopen($nombre_archivo, 'a');
fwrite($fd,$archivo);
fclose($fd);
?&gt;
</pre>
<p>Para m&aacute;s informaci&oacute;n, podemos leer la <a href="https://www.paypal.com/es/cgi-bin/webscr?cmd=_batch-payment-overview-outside">documentaci&oacute;n oficial de los pagos en serie</a>.</p>
<p>&nbsp;</p>
<h3>Art&iacute;culos relacionados:</h3>
<ul>
<li><a title="Utilizar PayPal para vender en tu web" href="http://www.imaginanet.com/blog/como-utilizar-paypal-para-realizar-compras-en-tu-web.html">C&oacute;mo pagar en tu web con PayPal</a></li>
<li><a title="PayPal Instant Payment Notification" href="http://www.imaginanet.com/blog/controlar-los-pagos-por-paypal-mediante-notificacion-de-pago-instantanea.html">Controlar los pagos por PayPal mediante Notificaci&oacute;n de Pago Instant&aacute;nea</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=45</wfw:commentRss>
			<slash:comments>3</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/pagos-en-serie-de-paypal.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Se terminan las IPs</title>
			<link>http://www.imaginanet.com/blog/se-terminan-las-ips.html</link>
			<guid>http://www.imaginanet.com/blog/se-terminan-las-ips.html</guid>
			<comments>http://www.imaginanet.com/blog/se-terminan-las-ips.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Thu, 13 May 2010 12:40:52 +0100</pubDate>
					<category><![CDATA[Internet]]></category>
					<description><![CDATA[Est&aacute; previsto que el a&ntilde;o que viene se agoten las direcciones ip seg&uacute;n el esquema IPv4, el cual se mejor&oacute; con el IPv6 pero muchas empresas y pa&iacute;ses todav&iacute;a no lo han implantado.Este hecho, implica que el d&iacute;a 9 de septiembre de 2012 se agotar&aacute;n las direcciones IP (seg&uacute;n...]]></description>
			<content:encoded><![CDATA[>Est&aacute; previsto que el a&ntilde;o que viene se agoten las direcciones ip seg&uacute;n el esquema IPv4, el cual se mejor&oacute; con el IPv6 pero muchas empresas y pa&iacute;ses todav&iacute;a no lo han implantado.<br /><br />Este hecho, implica que el d&iacute;a 9 de septiembre de 2012 se agotar&aacute;n las direcciones IP (seg&uacute;n los expertos, este d&iacute;a se entregar&aacute; el &uacute;ltimo rango de direcciones IP). El protocolo IPv4 permite 4.000 billones de direcciones IP, una cantidad suficiente cuando naci&oacute; la WWW, pero hoy en d&iacute;a es necesario ampliar el n&uacute;mero.]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=44</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/se-terminan-las-ips.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Cómo crear una campaña de publicidad en móviles. Claves a tener en cuenta.</title>
			<link>http://www.imaginanet.com/blog/como-crear-una-campana-de-publicidad-en-moviles-claves-a-tener-en-cuenta.html</link>
			<guid>http://www.imaginanet.com/blog/como-crear-una-campana-de-publicidad-en-moviles-claves-a-tener-en-cuenta.html</guid>
			<comments>http://www.imaginanet.com/blog/como-crear-una-campana-de-publicidad-en-moviles-claves-a-tener-en-cuenta.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Thu, 13 May 2010 12:34:18 +0100</pubDate>
					<category><![CDATA[Marketing OnLine]]></category>
					<description><![CDATA[Seg&uacute;n un estudio realizado en 2008 por la Uni&oacute;n Internacional de Telecomunicaciones, en el a&ntilde;o 2008 el 61% de la poblaci&oacute;n mudial dispon&iacute;a de tel&eacute;fono m&oacute;vil. Si tenemos en cuenta que ya hace dos a&ntilde;os de este informe y que la cifra es a nivel mundial, podemos decir que todas...]]></description>
			<content:encoded><![CDATA[>Seg&uacute;n un estudio realizado en 2008 por la Uni&oacute;n Internacional de Telecomunicaciones, en el a&ntilde;o 2008 <span style="text-decoration: underline;">el 61% de la poblaci&oacute;n mudial </span>dispon&iacute;a de tel&eacute;fono m&oacute;vil. Si tenemos en cuenta que ya hace dos a&ntilde;os de este informe y que la cifra es a nivel mundial, podemos decir que todas las personas son usuarios de tel&eacute;fono m&oacute;vil. Tenemos un porcentaje de poblaci&oacute;n casi total al que podemos enviarle un mensaje publicitario sin tener que saber donde est&aacute;n.<br /><br />El marketing m&oacute;vil tienen un potencial brutal, ya que la llegada de internet al m&oacute;vil lo ha convertido en una de las mejores opciones para dar a conocer o fomentar un producto, servicio o marca. Adem&aacute;s, es necesario tener en cuenta que al ser un medio personal, permite una segmentaci&oacute;n para la creaci&oacute;n de campa&ntilde;as publicitarias dise&ntilde;adas especialmente para el target al que se dirige.<br /><br /><span style="text-decoration: underline;">Cosas importantes a tener en cuenta cuando pensemos lanzar una campa&ntilde;a publicitaria dirigida a dispositivos m&oacute;viles:</span><br /><br />- <strong>P&aacute;ginas de llegada distintas dependiendo del tipo de m&oacute;vil</strong>: Al tener distintos dispositivos m&oacute;viles con distintas caracter&iacute;sticas, si queremos que nuestros contenidos sean compatibles con todos los modelos de m&oacute;vil, es necesario crear landing pages propias para cada uno.<br />- <strong>Dar contenidos interesantes</strong>. Si ofrecemos contenidos que aportan valor a&ntilde;adido a la campa&ntilde;a, provocamos un feedback positivo de los usuarios. Por ejemplo podemos enviar bonus descuento, promociones con descuentos, informaci&oacute;n interesante para el usuario, v&iacute;deos, etc, incrementaremos el ratio de usuarios atra&iacute;dos por la campa&ntilde;a.<br />- <strong>Utilizar varias opciones</strong>. Cuando se comienza con una estrategia publicitaria, es aconsejable realizar un test con cada modelo planteado para as&iacute; conocer cual funciona mejor con un servicio, marca o producto. El CTR de una campa&ntilde;a sin optimizar no supera el 3%, esta misma campa&ntilde;a optimizada para el target, puede darnos un CTR del 5% o superior.<br />- <strong>Piensa bien el mensaje que quieres transmitir</strong>. Los mensajes publicitarios deben ser cortos, directos y f&aacute;ciles de entender, si adem&aacute;s incluye contenidos virales como galer&iacute;as de fotos, videos, etc, el mensaje funciona por s&iacute; solo.<br /><br />Imaginanet es una <strong><a title="&quot;Imaginanet," href="/">agencia web</a></strong> que puede ayudarte con estrategias de marketing en nuevos medios.]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=43</wfw:commentRss>
			<slash:comments>1</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/como-crear-una-campana-de-publicidad-en-moviles-claves-a-tener-en-cuenta.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Posicionamiento en buscadores, la técnica de marketing online más eficaz</title>
			<link>http://www.imaginanet.com/blog/posicionamiento-en-buscadores-la-tecnica-de-marketing-online-mas-eficaz.html</link>
			<guid>http://www.imaginanet.com/blog/posicionamiento-en-buscadores-la-tecnica-de-marketing-online-mas-eficaz.html</guid>
			<comments>http://www.imaginanet.com/blog/posicionamiento-en-buscadores-la-tecnica-de-marketing-online-mas-eficaz.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Wed, 12 May 2010 11:57:08 +0100</pubDate>
					<category><![CDATA[SEO]]></category>
					<category><![CDATA[Marketing OnLine]]></category>
					<description><![CDATA[Acaba de hacerse p&uacute;blico un estudio en el que se destaca la t&eacute;cnica de posicionamiento en buscadores como la pr&aacute;ctica de marketing online m&aacute;s importante para todo negocio montado en la red.El posicionamiento en buscadores o SEO (Search Engine Optimization), tiene como objetivo que la web a posicionar...]]></description>
			<content:encoded><![CDATA[>Acaba de hacerse p&uacute;blico un estudio en el que se destaca la t&eacute;cnica de posicionamiento en buscadores como la pr&aacute;ctica de marketing online m&aacute;s importante para todo negocio montado en la red.<br /><br />El posicionamiento en buscadores o SEO (Search Engine Optimization), tiene como objetivo que la web a posicionar aparezca en primeras posiciones de b&uacute;squeda en los distintos buscadores de internet.<br /> <br />Seg&uacute;n los expertos, la optimizaci&oacute;n SEO ser&aacute; la m&aacute;s rentable y la m&aacute;s efectiva t&eacute;cnica de <a title="Imaginanet: Agencia de marketing online" href="/marketing-online.html">marketing online</a>, tanto para empresas que operen en internet u otras que no lo hagan pero tengan presencia. Esto confirma una encuesta que se hizo recientemente en la que el 95% de las pymes online consideran el posicionamiento en buscadores como la t&eacute;cnica de ventas m&aacute;s rentable para su empresa.<br /><br />Aunque se est&aacute; intentando tambi&eacute;n innovar y vender al usuario nuevas tendencias como lo son las redes sociales y otros entornos novedosos, actualmente la t&eacute;cnica m&aacute;s rentable es el SEO, aunque no hay que dejar de fijarse en medios como las redes sociales, ya que juegan un papel importante y jugar&aacute;n un papel m&aacute;s importante en el futuro en lo que respecta al posicionamiento en buscadores.<br /><br />Conclusi&oacute;n: una de las estrategias de <a title="Imaginanet, agencia de marketing online" href="/marketing-online.html">marketing online</a> m&aacute;s importante es el posicionamiento en buscadores.&nbsp;]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=42</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/posicionamiento-en-buscadores-la-tecnica-de-marketing-online-mas-eficaz.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Google lanza un tablet para competir con Apple iPad</title>
			<link>http://www.imaginanet.com/blog/google-lanza-un-tablet-para-competir-con-apple-ipad.html</link>
			<guid>http://www.imaginanet.com/blog/google-lanza-un-tablet-para-competir-con-apple-ipad.html</guid>
			<comments>http://www.imaginanet.com/blog/google-lanza-un-tablet-para-competir-con-apple-ipad.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Wed, 12 May 2010 11:35:17 +0100</pubDate>
					<category><![CDATA[Google]]></category>
					<description><![CDATA[Verizon en breve va a lanzar un tablet para cuyo lanzamiento cuenta con la ayuda tecnol&oacute;gica de Google.Seg&uacute;n se confirma en la noticia (ver en ingl&eacute;s), est&aacute;n trabajando con Google en el desarrollo del tablet para as&iacute; competir con AT&amp;T.Google s&oacute;lo ha dicho que su software est&aacute;...]]></description>
			<content:encoded><![CDATA[>Verizon en breve va a lanzar un tablet para cuyo lanzamiento cuenta con la ayuda tecnol&oacute;gica de Google.<br /><br />Seg&uacute;n se confirma en la noticia (<a title="Ver noticia original" href="http://online.wsj.com/article/SB10001424052748704250104575238680540806288.html?mod=WSJ_Tech_INTL_LSMODULE" target="_blank">ver en ingl&eacute;s</a>), est&aacute;n trabajando con Google en el desarrollo del tablet para as&iacute; competir con AT&amp;T.<br /><br />Google s&oacute;lo ha dicho que su software est&aacute; preparado para que se use en cualquier dispositivo, as&iacute; que se supone que usar&aacute; Android como sistema operativo.<br /><br />Esta noticia aumenta la guerra entre Google y Apple, que desde hace unos meses han comenzado una batalla que parece plantearse dura y larga.&nbsp;]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=41</wfw:commentRss>
			<slash:comments>1</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/google-lanza-un-tablet-para-competir-con-apple-ipad.html</feedburner:origLink>
		</item>
				
		<item>
			<title>En USA, las editoriales van con Google</title>
			<link>http://www.imaginanet.com/blog/en-usa-las-editoriales-van-con-google.html</link>
			<guid>http://www.imaginanet.com/blog/en-usa-las-editoriales-van-con-google.html</guid>
			<comments>http://www.imaginanet.com/blog/en-usa-las-editoriales-van-con-google.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Tue, 11 May 2010 11:15:22 +0100</pubDate>
					<category><![CDATA[Comercio electrónico]]></category>
					<category><![CDATA[Google]]></category>
					<description><![CDATA[El buscador americano Google, ha conseguido que las editoriales de Estados Unidos vean bien la entrada del buscador en el negocio de los libros electr&oacute;nicos, uno de los grandes intereses que Google ha declarado abiertamente.Parece ser que la tienda virtual (e-commerce) de libros electr&oacute;nicos (eBooks) de Google...]]></description>
			<content:encoded><![CDATA[>El buscador americano Google, ha conseguido que las editoriales de Estados Unidos vean bien la entrada del buscador en el negocio de los libros electr&oacute;nicos, uno de los grandes intereses que Google ha declarado abiertamente.<br /><br />Parece ser que la <a title="Imaginanet desarrolla tiendas virtuales / e-commerce apps" href="/diseno-web/tiendas-virtuales.html">tienda virtual (e-commerce)</a> de libros electr&oacute;nicos (eBooks) de Google empezar&aacute; a funcionar con m&aacute;s de 25.000 autores y editoriales en junio de este a&ntilde;o. De estos libros, 2 millones ha sido cedidos por las editoriales para poner en marcha la mayor biblioteca virtual del mundo. (<a href="http://www.japantoday.com/category/technology/view/google-backed-by-almost-all-us-publishers-on-digital-bookstore" target="_blank">ver noticia completa en ingl&eacute;s</a>)&nbsp;]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=40</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/en-usa-las-editoriales-van-con-google.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Internet ocupa el móvil de forma espectacular</title>
			<link>http://www.imaginanet.com/blog/internet-ocupa-el-movil-de-forma-espectacular.html</link>
			<guid>http://www.imaginanet.com/blog/internet-ocupa-el-movil-de-forma-espectacular.html</guid>
			<comments>http://www.imaginanet.com/blog/internet-ocupa-el-movil-de-forma-espectacular.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Tue, 11 May 2010 11:08:18 +0100</pubDate>
					<category><![CDATA[Google Apps]]></category>
					<category><![CDATA[Google]]></category>
					<category><![CDATA[Buscadores]]></category>
					<category><![CDATA[Web 2.0]]></category>
					<description><![CDATA[Sin darnos cuenta, hemos llegado a una situaci&oacute;n en que los proveedores de contenidos y aplicaciones web como son Google, FaceBook, Apple, Skype, Twitter, ..., tienen una cuota de poder alucinante en un sector con ingresos muy atractivos y m&aacute;rgenes de beneficio bastante amplios.Esta situaci&oacute;n est&aacute;...]]></description>
			<content:encoded><![CDATA[>Sin darnos cuenta, hemos llegado a una situaci&oacute;n en que los proveedores de contenidos y aplicaciones web como son Google, FaceBook, Apple, Skype, Twitter, ..., tienen una cuota de poder alucinante en un sector con ingresos muy atractivos y m&aacute;rgenes de beneficio bastante amplios.<br /><br />Esta situaci&oacute;n est&aacute; poniendo nerviosas a las compa&ntilde;&iacute;as de telecomunicaciones, que sin darse cuenta, han perdido en control total del sector que ten&iacute;an, ya que el negocio se basa m&aacute;s en las herramientas que estos proveedores de <a title="Aplicaciones web 2.0" href="/programacion-web/aplicaciones-web.html">aplicaciones web</a> proporcionan que en la mera gesti&oacute;n del tr&aacute;fico de voz y datos.<br /><br />Aunque ya han asumido que la comunicaci&oacute;n con voz no es su principal objetivo (nadie se ha opuesto a Skype, cuya aplicaci&oacute;n de comunicaci&oacute;n por voz la usan m&aacute;s de 500 millones de usuarios en todo el mundo), parece ser que esto no va a pasar con la publicidad, que tras el &eacute;xito conseguido por Google, todos quieren formar parte del negocio.<br /><br />La batalla de verdad s&oacute;lo acaba de empezar, veremos que posiciones toma cada uno de los participantes.&nbsp;]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=39</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/internet-ocupa-el-movil-de-forma-espectacular.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Android vs iPhone. En USA las ventas de Android superan a las de iPhone.</title>
			<link>http://www.imaginanet.com/blog/android-vs-iphone-en-usa-las-ventas-de-android-superan-a-las-de-iphone.html</link>
			<guid>http://www.imaginanet.com/blog/android-vs-iphone-en-usa-las-ventas-de-android-superan-a-las-de-iphone.html</guid>
			<comments>http://www.imaginanet.com/blog/android-vs-iphone-en-usa-las-ventas-de-android-superan-a-las-de-iphone.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Tue, 11 May 2010 10:55:55 +0100</pubDate>
					<category><![CDATA[Google Apps]]></category>
					<category><![CDATA[Google]]></category>
					<category><![CDATA[Buscadores]]></category>
					<category><![CDATA[Web 2.0]]></category>
					<description><![CDATA[Mientras Nokia sigue manteniendo el primer puesto a nivel mundial en lo que a ventas de tel&eacute;fonos m&oacute;viles se refiere.El sistema operativo Android, de Google, acaba de ocupar la segunda plaza de ventas en Estados Unidos, puesto que ocupaba el iPhone de Apple (ver noticia). As&iacute;, tenemos en primer puesto a...]]></description>
			<content:encoded><![CDATA[>Mientras Nokia sigue manteniendo el primer puesto a nivel mundial en lo que a ventas de tel&eacute;fonos m&oacute;viles se refiere.<br /><br />El sistema operativo Android, de Google, acaba de ocupar la segunda plaza de ventas en Estados Unidos, puesto que ocupaba el iPhone de Apple (<a title="Ver noticia" href="http://www.npd.com/press/releases/press_100510.html" target="_blank">ver noticia</a>). As&iacute;, tenemos en primer puesto a BlackBerry (36%), le sigue Android (28%) y en tercera posici&oacute;n est&aacute; iPhone (21%), seg&uacute;n la noticia, este impulso en ventas se ha debido a las campa&ntilde;as promocionales que han llevado a cabo dos empresas de telefon&iacute;a m&oacute;vil, por otro lado, hay que tener en cuenta que en USA s&oacute;lo una operadora (ATT) vende el iPhone en exclusiva.<br /><br />Seg&uacute;n Apple, desde el lanzamiento del iPhone en 2007 se han vendido 51 millones de tel&eacute;fonos y en el Application Store est&aacute;n disponibles m&aacute;s de 200.000 aplicaciones.&nbsp;<br /><br />Distintos informes de ventas de tel&eacute;fonos de &uacute;ltima generaci&oacute;n dan el liderazgo a Nokia, la segunda plaza es para RIM (BlackBerry), el tercer puesto es para Apple y el cuarto lo ocupa Android.&nbsp;]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=38</wfw:commentRss>
			<slash:comments>1</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/android-vs-iphone-en-usa-las-ventas-de-android-superan-a-las-de-iphone.html</feedburner:origLink>
		</item>
				
		<item>
			<title>La alternativa de Apple a Flash</title>
			<link>http://www.imaginanet.com/blog/la-alternativa-de-apple-a-flash.html</link>
			<guid>http://www.imaginanet.com/blog/la-alternativa-de-apple-a-flash.html</guid>
			<comments>http://www.imaginanet.com/blog/la-alternativa-de-apple-a-flash.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Mon, 10 May 2010 15:03:36 +0100</pubDate>
					<category><![CDATA[HTML5]]></category>
					<category><![CDATA[Flash]]></category>
					<category><![CDATA[Web 2.0]]></category>
					<category><![CDATA[JavaScript]]></category>
					<description><![CDATA[Por todos es conocida la disputa entre Apple y Adobe en cuanto a Adobe Flash.Hoy nos hemos enterado (ver noticia en ingl&eacute;s) de que Apple est&aacute; trabajando en el desarrollo de un framework basado en est&aacute;ndares web y que ser&aacute; la alternativa a Adobe Flash y Microsoft Silverlight. Lo m&aacute;s atractivo de...]]></description>
			<content:encoded><![CDATA[>Por todos es conocida la disputa entre Apple y Adobe en cuanto a Adobe Flash.<br /><br />Hoy nos hemos enterado (<a href="http://news.cnet.com/8301-13579_3-20004509-37.html" target="_blank">ver noticia en ingl&eacute;s</a>) de que Apple est&aacute; trabajando en el desarrollo de un framework basado en est&aacute;ndares web y que ser&aacute; la alternativa a Adobe Flash y Microsoft Silverlight. Lo m&aacute;s atractivo de todo es que se ejecutar&aacute; de forma nativa en los navegadores, con lo que no necesitar&aacute; de plugin adicional. El nombre que le han dado es Apple Gianduia.<br /><br />Podemos resumirlo como una adaptaci&oacute;n de Cocoa, CoreData y WebObjects pero en los navegadores y estar&aacute; escrito en JavaScript. Seg&uacute;n parece ser, Apple ha utilizado Gianduia ya en el programa de reservas inclu&iacute;do en iPhone y en varias aplicaciones de tiendas virtuales online.<br /><br />Parece que Apple contra-ataca a Flash con Gianduia.<br /><br />Un nuevo punto a tener en cuenta por <a title="Imaginanet, empresa de dise&ntilde;o web profesional" href="/diseno-web.html">empresas de dise&ntilde;o web</a> y que habr&aacute; que seguir con atenci&oacute;n.]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=34</wfw:commentRss>
			<slash:comments>2</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/la-alternativa-de-apple-a-flash.html</feedburner:origLink>
		</item>
				
		<item>
			<title>La compañía japonesa NEC anuncia una tecnología con la que encontrará vídeos piratas en pocos segundos</title>
			<link>http://www.imaginanet.com/blog/la-compania-japonesa-nec-anuncia-una-tecnologia-con-la-que-encontrara-videos-piratas-en-pocos-segundos.html</link>
			<guid>http://www.imaginanet.com/blog/la-compania-japonesa-nec-anuncia-una-tecnologia-con-la-que-encontrara-videos-piratas-en-pocos-segundos.html</guid>
			<comments>http://www.imaginanet.com/blog/la-compania-japonesa-nec-anuncia-una-tecnologia-con-la-que-encontrara-videos-piratas-en-pocos-segundos.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Mon, 10 May 2010 14:53:32 +0100</pubDate>
					<category><![CDATA[HTML5]]></category>
					<category><![CDATA[Flash]]></category>
					<category><![CDATA[Web 2.0]]></category>
					<category><![CDATA[JavaScript]]></category>
					<description><![CDATA[NEC ha anunciado (ver noticia en ingl&eacute;s) que dispone de una tecnolog&iacute;a de identificaci&oacute;n que permitir&aacute; a los propietarios de derechos de autor buscar en pocos segundos v&iacute;deos que cometen infracciones de copyright y est&aacute;n subidos a internet.En la nota de prensa se anuncia como gran invento...]]></description>
			<content:encoded><![CDATA[>NEC ha anunciado (<a href="http://www.tcmagazine.com/tcm/news/misc/27909/nec-claims-find-illegal-video-uploads-seconds" target="_blank">ver noticia en ingl&eacute;s</a>) que dispone de una tecnolog&iacute;a de identificaci&oacute;n que permitir&aacute; a los propietarios de derechos de autor buscar en pocos segundos v&iacute;deos que cometen infracciones de copyright y est&aacute;n subidos a internet.<br /><br />En la nota de prensa se anuncia como gran invento para acabar con la pirater&iacute;a en internet con este sistema capaz de encontrar copias completas id&eacute;nticas o modificadas de una pel&iacute;cula, video clip, ... que est&aacute;n en internet.<br /><br />Seg&uacute;n comentan es un sistema con una precisi&oacute;n superior al 96% y que da una tasa de falsos positivos del 5 por mill&oacute;n durante las pruebas que han realizado. NEC va a presentar esta tecnolog&iacute;a la semana que viene en una conferencia de "embeded systems".<br /><br />Este sistema se podr&aacute; implantar a partir de Septiembre. Su objetivo es la identificaci&oacute;n r&aacute;pida de infracciones de copyright en la red.<br /><br />&iquest;Qu&eacute; os parece?&nbsp;]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=33</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/la-compania-japonesa-nec-anuncia-una-tecnologia-con-la-que-encontrara-videos-piratas-en-pocos-segundos.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Google Apps para educación llega a los 8 millones de usuarios</title>
			<link>http://www.imaginanet.com/blog/google-apps-para-educacion-llega-a-los-8-millones-de-usuarios.html</link>
			<guid>http://www.imaginanet.com/blog/google-apps-para-educacion-llega-a-los-8-millones-de-usuarios.html</guid>
			<comments>http://www.imaginanet.com/blog/google-apps-para-educacion-llega-a-los-8-millones-de-usuarios.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Mon, 10 May 2010 15:20:01 +0100</pubDate>
					<category><![CDATA[Google Apps]]></category>
					<description><![CDATA[Google ha comunicado esta noticia en su blog oficial (ver post oficial), y esta noticia nos deja ver c&oacute;mo el master de las b&uacute;squedas invierte en su suite ofim&aacute;tica y soluci&oacute;n de comunicaci&oacute;n para grupos.Si tenemos en cuenta que Google Apps cuenta con un total de 25 millones de usuarios, se ve que...]]></description>
			<content:encoded><![CDATA[>Google ha comunicado esta noticia en su blog oficial (<a href="http://googleblog.blogspot.com/2010/05/schools-are-almost-out-for-summerand-in.html" target="_blank">ver post oficial</a>), y esta noticia nos deja ver c&oacute;mo el master de las b&uacute;squedas invierte en su suite ofim&aacute;tica y soluci&oacute;n de comunicaci&oacute;n para grupos.<br /><br />Si tenemos en cuenta que Google Apps cuenta con un total de 25 millones de usuarios, se ve que casi un tercio son del sistema educativo. Una apuesta estrat&eacute;gica con estas herramientas gratuitas que integran Gmail, Gcalendar, Gtalk, &nbsp;Gdocs, Gpages, ... con la opci&oacute;n de compartirlos y editarlos conjuntamente.<br />]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=35</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/google-apps-para-educacion-llega-a-los-8-millones-de-usuarios.html</feedburner:origLink>
		</item>
				
		<item>
			<title>225 millones de euros para las TIC</title>
			<link>http://www.imaginanet.com/blog/225-millones-de-euros-para-las-tic.html</link>
			<guid>http://www.imaginanet.com/blog/225-millones-de-euros-para-las-tic.html</guid>
			<comments>http://www.imaginanet.com/blog/225-millones-de-euros-para-las-tic.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Mon, 10 May 2010 15:40:18 +0100</pubDate>
					<category><![CDATA[Google Apps]]></category>
					<description><![CDATA[La Secretar&iacute;a de Estado de Telecomunicaciones anunci&oacute; el inicio de la convocatoria para la concesi&oacute;n de ayudas en el marco del Plan Avanza. El Gobierno destinar&aacute; en 2010, 225 millones de euros a trav&eacute;s de cuatro l&iacute;neas: Formaci&oacute;n, Competitividad (I+D+i), Ciudadan&iacute;a Digital y...]]></description>
			<content:encoded><![CDATA[>La Secretar&iacute;a de Estado de Telecomunicaciones anunci&oacute; el inicio de la convocatoria para la concesi&oacute;n de ayudas en el marco del Plan Avanza. <br /><br />El Gobierno destinar&aacute; en 2010, 225 millones de euros a trav&eacute;s de cuatro l&iacute;neas: <br />Formaci&oacute;n, Competitividad (I+D+i), Ciudadan&iacute;a Digital y Contenidos de Inter&eacute;s Social.  <br /><br />159 millones de euros se destinar&aacute;n a prestamos y los 66 millones de euros restantes&nbsp;se entregar&aacute;n a trav&eacute;s de subvenciones. <br /><br />El Ministerio de Industria ha publicado una nota de prensa en la que dice que la convocatoria busca contribuir al &ldquo;<em>adecuado desarrollo y utilizaci&oacute;n de las tecnolog&iacute;as, aplicaciones, servicios y contenidos para la sociedad de la informaci&oacute;n</em>&rdquo;.  <br /><br />Desde el Gobierno se insiste en la necesidad de consolidar un modelo de crecimiento econ&oacute;mico sostenible que se base en &ldquo;<em>el incremento de la competitividad y la productividad, la promoci&oacute;n de la igualdad social y regional, la accesibilidad universal y la mejora del bienestar y la calidad de vida de los ciudadanos</em>&rdquo;.  <br /><br />El programa Avanza Competitividad (I+D+i) tiene el presupuesto m&aacute;s alto: 200 millones de euros (150 millones en pr&eacute;stamos y 50 millones en subvenciones). <br /><br />Las solicitudes podr&aacute;n presentarse entre el 7 de mayo y el 7 de junio.  <br /><br />Avanza Contenidos de Inter&eacute;s Social, por su parte, cuenta con un presupuesto de 12 millones de euros (9 millones pr&eacute;stamos y 3 millones en subvenciones) y recibir&aacute; solicitudes entre el 7 de mayo y el 14 de junio.  <br /><br />El presupuesto de Avanza Formaci&oacute;n llega a los 10 millones de euros en subvenciones, con un plazo de presentaci&oacute;n de solicitudes del 7 de mayo al 9 de junio. <br /> <br />Avanza Ciudadan&iacute;a Digital, por &uacute;ltimo, dispone de un presupuesto de 3 millones de euros en subvenciones y aceptar&aacute; solicitudes entre el 7 de mayo y el 1 de junio.]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=37</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/225-millones-de-euros-para-las-tic.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Google cambia el buscador</title>
			<link>http://www.imaginanet.com/blog/google-cambia-el-buscador.html</link>
			<guid>http://www.imaginanet.com/blog/google-cambia-el-buscador.html</guid>
			<comments>http://www.imaginanet.com/blog/google-cambia-el-buscador.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Mon, 10 May 2010 15:34:49 +0100</pubDate>
					<category><![CDATA[Google]]></category>
					<category><![CDATA[SEO]]></category>
					<description><![CDATA[Desde hoy se puede ver c&oacute;mo en la parte izquierda del resultado de una b&uacute;squeda nos aparece un men&uacute; nuevo con b&uacute;squeda de im&aacute;genes, libros, noticias, blogs, ... y una vez elegida una opci&oacute;n nos ofrece m&aacute;s opciones sobre el tema/opci&oacute;n elegido (tama&ntilde;os de imagen, color,...]]></description>
			<content:encoded><![CDATA[>Desde hoy se puede ver c&oacute;mo en la parte izquierda del resultado de una b&uacute;squeda nos aparece un men&uacute; nuevo con b&uacute;squeda de im&aacute;genes, libros, noticias, blogs, ... y una vez elegida una opci&oacute;n nos ofrece m&aacute;s opciones sobre el tema/opci&oacute;n elegido (tama&ntilde;os de imagen, color, ...).<br /><br />Se supone que con estos cambios Google pretende ganar en <a title="Dise&ntilde;o web y usabilidad" href="/diseno-web/diseno-web-y-usabilidad.html">usabilidad</a> y ahorrarse p&aacute;ginas vistas de los usuarios. En Google dicen en que el ahorro de tiempo para el usuario ser&aacute; muy grande, ya que podr&aacute; ir a lo que busca de forma directa. El usuario tiene m&aacute;s f&aacute;cilmente en pantalla lo que busca.<br /><br />Adem&aacute;s, han aplicado unas peque&ntilde;as variaciones est&eacute;ticas al buscador como eliminar subrayado de enlaces, degradados, etc.&nbsp;]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=36</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/google-cambia-el-buscador.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Las 6 razones de Apple para no utilizar Flash</title>
			<link>http://www.imaginanet.com/blog/las-6-razones-de-apple-para-no-utilizar-flash.html</link>
			<guid>http://www.imaginanet.com/blog/las-6-razones-de-apple-para-no-utilizar-flash.html</guid>
			<comments>http://www.imaginanet.com/blog/las-6-razones-de-apple-para-no-utilizar-flash.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Mon, 10 May 2010 12:12:59 +0100</pubDate>
					<category><![CDATA[HTML5]]></category>
					<category><![CDATA[Accesibilidad]]></category>
					<category><![CDATA[Flash]]></category>
					<category><![CDATA[Web 2.0]]></category>
					<description><![CDATA[Steve Jobs, m&aacute;ximo responsable de Apple ha criticado abiertamente a Adobe en esta carta. En la carta se defienden los est&aacute;ndares abiertos para web, como HTML5&nbsp;.Los seis motivos por los que Flash no funciona en sus dispositivos iPhone, iPod e iPad son:- Flash es de la era de los ratones y no de las pantallas...]]></description>
			<content:encoded><![CDATA[>Steve Jobs, m&aacute;ximo responsable de Apple ha criticado abiertamente a Adobe en <a title="Ver carta. En ingl&eacute;s." href="http://www.apple.com/hotnews/thoughts-on-flash/" target="_blank">esta carta</a>. En la carta se defienden los est&aacute;ndares abiertos para web, como HTML5&nbsp;.<br /><br />Los seis motivos por los que Flash no funciona en sus dispositivos iPhone, iPod e iPad son:<br />- Flash es de la era de los ratones y no de las pantallas t&aacute;ctiles.<br />- Flash no es abierto como lo son HTML, CSS y JavaScript<br />- No es seguro y tampoco es estable.<br />- Gasta m&aacute;s bater&iacute;a en la descodificaci&oacute;n que en el caso de H.264<br />- Flash es multiplataforma y es necesario estar pendientes de cuando Adobe proporciona herramientas para desarrolladores.<br /><br />En definitiva, se aconseja utilizar HTML 5.<br /><br />Imaginanet es una <a title="Agencia web, marketing online y programaci&oacute;n web." href="/">agencia web</a> que desarrolla <a title="Desarrollo y consultor&iacute;a de aplicaciones web" href="/programacion-web/aplicaciones-web.html">aplicaciones web</a> 100% compatibles con todos los dispositivos m&oacute;viles.&nbsp;]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=32</wfw:commentRss>
			<slash:comments>3</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/las-6-razones-de-apple-para-no-utilizar-flash.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Optimización de código PHP</title>
			<link>http://www.imaginanet.com/blog/optimizacion-de-codigo-php.html</link>
			<guid>http://www.imaginanet.com/blog/optimizacion-de-codigo-php.html</guid>
			<comments>http://www.imaginanet.com/blog/optimizacion-de-codigo-php.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Thu, 22 Apr 2010 15:59:48 +0100</pubDate>
					<category><![CDATA[PHP]]></category>
					<description><![CDATA[Cuando tenemos planeado hacer una aplicaci&oacute;n web que va a hacer un trabajo intensivo de operaciones, base de datos, ficheros, etc. (por ejemplo p&aacute;gina corporativa o de comercio electr&oacute;nico) debemos plantearnos la velocidad final que tendr&aacute; con una alta carga de visitas diarias.
Por ello, vamos a...]]></description>
			<content:encoded><![CDATA[><p>Cuando tenemos planeado hacer una aplicaci&oacute;n web que va a hacer un trabajo intensivo de operaciones, base de datos, ficheros, etc. (por ejemplo <a title="Programaci&oacute;n y dise&ntilde;o de p&aacute;ginas web corporativas y de comercio electr&oacute;nico" href="http://www.imaginanet.com/programacion-web.html">p&aacute;gina corporativa o de comercio electr&oacute;nico</a>) debemos plantearnos la velocidad final que tendr&aacute; con una alta carga de visitas diarias.</p>
<p>Por ello, vamos a explicar algunos trucos y consejos con ejemplos para poder escribir nuestro c&oacute;digo PHP optimizado y por tanto nuestras aplicaciones corran m&aacute;s r&aacute;pido.</p>
<h3><span style="text-decoration: underline;">Cadenas de texto</span></h3>
<p><strong>Usar echo en vez de print</strong></p>
<p>Es m&aacute;s r&aacute;pido hacer uso de la funci&oacute;n echo que de la funci&oacute;n print</p>
<pre class="code php">echo &ldquo;Hola&rdquo;; // M&aacute;s r&aacute;pido
print &ldquo;Hola&rdquo;;
</pre>
<p><strong>Evitar concatenar texto innecesariamente y utilizar m&uacute;ltiples echos</strong></p>
<p>Es mejor realizar dos salidas de texto con dos echos diferentes que concatenar texto y despu&eacute;s producir la salida.</p>
<pre class="code php">echo &ldquo;Bienvenido&rdquo;; echo $usuario; // M&aacute;s r&aacute;pido
echo &ldquo;Bienvenido&rdquo;.$usuario;
</pre>
<p><strong>Saber si una cadena de texto est&aacute; vac&iacute;a</strong></p>
<p>Es m&aacute;s r&aacute;pido saber si una variable est&aacute; vac&iacute;a con empty que saber si la longitud en n&uacute;mero de caracteres es cero con strlen.</p>
<pre class="code php">if (empty($cadena)) echo &ldquo;vac&iacute;a&rdquo;; // M&aacute;s r&aacute;pida
if (strlen($s) == 0) echo &ldquo;vac&iacute;a&rdquo;;
</pre>
<p><strong>Substituir texto</strong></p>
<p>La manera m&aacute;s r&aacute;pida para substituir texto es con strtr y no con str_replace o preg_replace.</p>
<pre class="code php">$salida = strtr("abd","d","c"); // M&aacute;s r&aacute;pida
$salida = str_replace("d","c","abd");
$salida = preg_replace("/d/","c","abd");
</pre>
<p><strong>Saber si una cadena est&aacute; contenida en otra</strong></p>
<p>La funci&oacute;n strpos es m&aacute;s r&aacute;pida y ocupa menos memoria que strstr</p>
<pre class="code php">if(strpos("Hola","o")!==false) echo "s&iacute;"; // M&aacute;s r&aacute;pida
$esta_contenida = strstr("Hola","o");
if(!empty($esta_contenida)) echo "s&iacute;";
</pre>
<h3><span style="text-decoration: underline;">Variables y arrays</span></h3>
<p><strong>Uso de variables locales</strong></p>
<p>Es m&aacute;s r&aacute;pido y eficiente en memoria trabajar con variables locales dentro de una funci&oacute;n que con una variable de instancia de un objeto, declarada como global o sin definir:</p>
<pre class="code php">class objeto {
&nbsp;&nbsp;&nbsp;private $c;
&nbsp;&nbsp;&nbsp;public function __Construct() {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;c=0;
&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;public function prueba() {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Inicializaci&oacute;n
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;global $a;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$b = 0;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Incremento
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$a++;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$b++;	// M&aacute;s r&aacute;pida
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;c++;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$d++;
&nbsp;&nbsp;&nbsp;}
}
</pre>
<p><strong>Coste de memoria</strong></p>
<p>Deberemos declarar variables que vayamos a usar. Si vamos a usar una variable con valores temporales podemos llamarla $auxiliar y as&iacute; no declarar muchas variables diferentes que s&oacute;lo usamos una vez.</p>
<p>Las variables que ocupen mucho espacio en memoria, por ejemplo un array muy grande, deberemos borrarlas cuando no se vayan usar con la funci&oacute;n unset.</p>
<p><strong>Calcular la longitud de un array antes de recorrerlo</strong></p>
<p>Es m&aacute;s r&aacute;pido recorrer un array de la siguiente forma</p>
<pre class="code php">$icount = count($lista);
for($i=0;$i&lt;$icount;$i++) {
&nbsp;&nbsp;&nbsp;...
}
</pre>
<p>que de &eacute;sta</p>
<pre class="code php">for($i=0;$i&lt;count($lista);$i++) {
&nbsp;&nbsp;&nbsp;...
}
</pre>
<p>ya que el c&aacute;lculo de count se realiza tantas veces como posiciones tenga el array.</p>
<p><strong>Acceder correctamente a un &iacute;ndice no n&uacute;merico</strong></p>
<p>Debemos acceder a los &iacute;ndices no num&eacute;ricos de un array especific&aacute;ndolo con comillas</p>
<pre class="code php">echo $lista[0]['nombre']; // M&aacute;s r&aacute;pido
echo $lista[0][nombre];
</pre>
<h3><span style="text-decoration: underline;">Funciones y objetos</span></h3>
<p><strong>Hacer uso de las funciones predefinidas en PHP</strong></p>
<p>Las funciones incluidas en PHP siempre ser&aacute;n mucho m&aacute;s r&aacute;pidas que las que podamos hacer nosotros</p>
<p><strong>Uso de include y require</strong></p>
<p>Es m&aacute;s r&aacute;pido hacer uso de include o require que include_once o require_once.</p>
<p><strong>Funciones declaradas en objetos hijos son m&aacute;s r&aacute;pidos que los heredados</strong></p>
<p>Una funci&oacute;n declarada en un objeto hijo es m&aacute;s r&aacute;pida que una funci&oacute;n heredada de un objeto padre.</p>
<h3><span style="text-decoration: underline;">Bases de datos</span></h3>
<p><strong>Ordenar los resultados de m&uacute;ltiples consultas</strong></p>
<p>Cuando tenemos que hacer m&uacute;ltiples consultas SQL que terminen siendo pesadas, es mejor realizar el procesamiento de ordenaci&oacute;n mediante la funci&oacute;n <a href="http://es.php.net/manual/en/function.usort.php">usort</a> o similares que mediante SQL. Un ejemplo acerca de esto pod&eacute;is leer en el <a href="http://highscalability.com/blog/2010/3/23/digg-4000-performance-increase-by-sorting-in-php-rather-than.html">siguiente art&iacute;culo</a> de como Digg consigui&oacute; optimizar su web notablemente mediante estos procedimientos.</p>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=31</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/optimizacion-de-codigo-php.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Palo como solución de Business Intelligence: primeros pasos creando informes</title>
			<link>http://www.imaginanet.com/blog/palo-como-solucion-de-business-intelligence-primeros-pasos-creando-informes.html</link>
			<guid>http://www.imaginanet.com/blog/palo-como-solucion-de-business-intelligence-primeros-pasos-creando-informes.html</guid>
			<comments>http://www.imaginanet.com/blog/palo-como-solucion-de-business-intelligence-primeros-pasos-creando-informes.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Wed, 14 Apr 2010 11:06:41 +0100</pubDate>
					<category><![CDATA[Business Intelligence]]></category>
					<category><![CDATA[Comercio electrónico]]></category>
					<description><![CDATA[El t&eacute;rmino Business Intelligence (BI) o Inteligencia Empresarial es el uso de datos de esa propia empresa para conocer en mayor profundidad los hechos que se producen en los movimientos de clientes, ventas, gastos, etc. de esa manera podremos conocer fuentes de beneficios y gastos en base a los informes que de manera...]]></description>
			<content:encoded><![CDATA[>El t&eacute;rmino <em>Business Intelligence</em> (BI) o Inteligencia Empresarial es el uso de datos de esa propia empresa para conocer en mayor profundidad los hechos que se producen en los movimientos de clientes, ventas, gastos, etc. de esa manera podremos conocer fuentes de beneficios y gastos en base a los informes que de manera sencilla permite generar.
<h3>Jedox Palo</h3>
<p>Palo es un herramienta OLAP (<em><strong>O</strong>nline <strong>A</strong>nalytical <strong>P</strong>rocessing</em>) de BI, que nos permite crear almacenar datos y generar informes en <span style="text-decoration: underline;">hojas de c&aacute;lculo</span> (via Microsoft Excel / OpenOffice) <span style="text-decoration: underline;">o en el navegador Web</span>. Esta herramienta est&aacute; creada por la empresa Jedox y en las aplicaciones b&aacute;sicas son software libre, por lo que nos permite el uso b&aacute;sico a un costo cero, y adem&aacute;s posee de herramientas m&aacute;s avanzadas de pago.</p>
<h3>Instalando lo necesario</h3>
<p>Lo primero ser&aacute; descargarnos de la <a title="P&aacute;gina oficial de Palo de Jedox" href="http://www.jedox.com" target="_blank">p&aacute;gina oficial de Palo</a> el cliente (Palo for Excel o Palo for Open Office) y el el servidor (Palo Suite) e instalarlo primero el cliente y despu&eacute;s el servidor, si no podr&iacute;a haber alg&uacute;n problema en la instalaci&oacute;n. Adem&aacute;s, debemos bajarnos el manual de uso y configuraci&oacute;n para conocer ciertas funcionalidades y configuraciones.</p>
<p>Para esta instalaci&oacute;n, vamos a suponer que la instalaci&oacute;n que hagamos el cliente y el servidor van a estar en el mismo ordenador. Si queremos que el servidor est&eacute; abierto deberemos abrir el puerto en la configuraci&oacute;n del servidor Palo.</p>
<h4>NOTA: Instalando el complemento de Palo en OpenOffice</h4>
<p>Inicialmente la instalaci&oacute;n del addin de Palo lo hice sobre Excel sin problemas en Office XP. Sin embargo not&eacute; que si quer&iacute;amos hacerlo para OpenOffice bajo Linux mostraba un error Java. Tras buscar un poco por Google encontr&eacute; la siguiente p&aacute;gina <a title="Instalando Palo Addin en OpenOffice " href="http://software.krimnet.com/guide/guide-install-palooca-ubuntu-904-netbook-remix.htm" target="_blank">http://software.krimnet.com/guide/guide-install-palooca-ubuntu-904-netbook-remix.htm</a> en la que que explica los paquetes necesarios para instalarlo bajo Debian/Ubuntu.</p>
<h3>Primeros pasos creando informes con Excel o  OpenOffice</h3>
<p>Ahora arrancaremos nuestra hoja de c&aacute;lculo, si es desde Excel deberemos hacerlo haciendo doble click en el icono Palo Excel-Addin del escritorio, y veremos que tenemos una nueva opci&oacute;n que es la pesta&ntilde;a Palo.</p>
<p>Para crear un informe seleccionaremos la opci&oacute;n Pegar Vista. Las opciones b&aacute;sicas que se muestran son las siguientes:</p>
<ul>
<li><span style="text-decoration: underline;">Servidor / Base de datos:</span> nuestro ordenador se puede conectar a varios servidores que contengan diferentes bases de datos. En principio trabajaremos con la base de datos Demo.</li>
<li><span style="text-decoration: underline;">&Aacute;rea de hoja:</span> son las dimensiones de las que disponemos. Podemos definir una dimensi&oacute;n como un dato medible, como por ejemplo: productos, ventas, a&ntilde;os, clientes, etc.</li>
<li><span style="text-decoration: underline;">T&iacute;tulo de columna:</span> dimensi&oacute;n/es que ir&aacute;n en el eje X, en nuestro caso arrastraremos hasta aqu&iacute; la dimensi&oacute;n Years.</li>
<li><span style="text-decoration: underline;">T&iacute;tulo de rengl&oacute;n:</span> dimensi&oacute;n/es que ir&aacute;n en el eje Y, arrastraremos la dimensi&oacute;n Products.</li>
</ul>
<p>Tras seleccionarlo pulsaremos el bot&oacute;n insertar y el informe quedar&aacute; creado.</p>
<p><img title="Esquema de la vista de Palo" src="http://www.imaginanet.com/blog_files/palo/palo_esquema.png" alt="Esquema de la vista de Palo" /></p>
<p>Podemos ver que la vista consisten en dos zonas: la zona superior contiene las dimensiones no escogidas y la inferior contiene las dimensiones escogidas que queremos ver en detalle.</p>
<p>Si hacemos doble click sobre las celdas azules de la zona inferior podemos ir desplegando las secciones de a&ntilde;os o productos, subdividi&eacute;ndose en otras secciones hasta llegar a un elemento final. Mientras, en las celdas amarillas se muestra el valor calculado.</p>
<p>Podemos seleccionar las dimensiones de la zona superior para modificar el informe. Por ejemplo podemos hacer doble click sobre <em>Europe</em> y elegir <em>Spain</em>, todos los datos de la zona inferior que ahora salen son los pertenecientes a Espa&ntilde;a, pudiendo ver en detalle los valores para los productos seg&uacute;n a&ntilde;os.</p>
<p>Por &uacute;ltimo, tras tener el informe que deseamos, si queremos exportarlo y visualizarlo en un ordenador sin que tenga Palo instalado, podemos pulsar la opci&oacute;n <em>Guardar como Instant&aacute;nea</em>, pero este informe no ser&aacute; din&aacute;mico y s&oacute;lo veremos los datos visualizados al generarlo.</p>
<h3>Fuentes y m&aacute;s informaci&oacute;n</h3>
<ul>
<li><span style="text-decoration: underline;">Wikipedia</span>, Business Intelligence: <a title="Wikipedia Business Intelligence" href="http://es.wikipedia.org/wiki/Business_intelligence" target="_blank">http://es.wikipedia.org/wiki/Business_intelligence</a></li>
<li><span style="text-decoration: underline;">Wikipedia</span>, OLAP: <a title="Wikipedia OLAP" href="http://es.wikipedia.org/wiki/OLAP" target="_blank">http://es.wikipedia.org/wiki/OLAP</a></li>
<li><span style="text-decoration: underline;">Jedox</span>, Palo: <a title="Jedox Palo" href="http://www.jedox.com/" target="_blank">http://www.jedox.com/</a></li>
</ul>
<p>&nbsp;</p>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=30</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/palo-como-solucion-de-business-intelligence-primeros-pasos-creando-informes.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Seguridad en PHP básica: escribiendo aplicaciones web seguras</title>
			<link>http://www.imaginanet.com/blog/seguridad-en-php-basica-escribiendo-aplicaciones-web-seguras.html</link>
			<guid>http://www.imaginanet.com/blog/seguridad-en-php-basica-escribiendo-aplicaciones-web-seguras.html</guid>
			<comments>http://www.imaginanet.com/blog/seguridad-en-php-basica-escribiendo-aplicaciones-web-seguras.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Wed, 31 Mar 2010 09:29:59 +0100</pubDate>
					<category><![CDATA[PHP]]></category>
					<description><![CDATA[A continuaci&oacute;n vamos a explicar algunos conceptos b&aacute;sicos de brechas de seguridad m&aacute;s comunes y como solucionarlos mediante PHP permitiendo escribir aplicaciones web un poco m&aacute;s seguras.
Protecci&oacute;n contra la inyecci&oacute;n de c&oacute;digo SQL
Es muy com&uacute;n trabajar contra una base de...]]></description>
			<content:encoded><![CDATA[><p>A continuaci&oacute;n vamos a explicar algunos conceptos b&aacute;sicos de brechas de seguridad m&aacute;s comunes y como solucionarlos mediante PHP permitiendo escribir <a title="Desarrollo de aplicaciones web a medida" href="/programacion-web/aplicaciones-web.html">aplicaciones web</a> un poco m&aacute;s seguras.</p>
<h3>Protecci&oacute;n contra la inyecci&oacute;n de c&oacute;digo SQL</h3>
<p>Es muy com&uacute;n trabajar contra una base de datos (MySQL, PostgreSQL, Oracle, etc.) y estas consultas dependen de par&aacute;metros llegados desde GET o POST, por lo que permitimos al usuario de cada web que en cierta manera modifique las consultas SQL de nuestra web.</p>
<p>Esto podr&iacute;a provocar que un usuario que construya una consulta SQL malintencionada pudiera obtener resultados indeseados, como poder hacer un login en una zona restringida de nuestra web sin conocer ning&uacute;n usuario / contrase&ntilde;a.</p>
<p>Supongamos la siguiente situaci&oacute;n: tenemos un <strong>nombre de usuario pruebas</strong> y una <strong>contrase&ntilde;a clave_pruebas</strong> guardados en base de datos. Para realizar la identificador obtenemos los par&aacute;metros por POST mediante las variables $_POST['usuario']  y $_POST['clave']. Tras ello realizamos la siguiente consulta SQL:</p>
<pre class="code php">mysql_query('select id from usuariosWeb where usuario = '".$_POST['usuario']."' and password = '".$_POST['clave']."'');</pre>
<p>Si existe un usuario con ese nombre y usuario, es que la identificaci&oacute;n es correcta y por tanto debemos hacer el login. Pero sin embargo, si construy&eacute;semos el siguiente par&aacute;metro</p>
<pre class="code php">$_POST['clave'] ="m' or 1='1"</pre>
<p>podemos observar que nos devuelve un valor v&aacute;lido para identificarse conociendo s&oacute;lo el nombre de usuario.</p>
<p>Para solucionarlo, tenemos diversos m&eacute;todos pero lo m&aacute;s c&oacute;modo es substituir las comillas simples y dobles de todos los par&aacute;metros par&aacute;metros POST mediante el siguiente c&oacute;digo:</p>
<pre class="code php">foreach($_POST as $key =&gt; $value) {
	$_POST[$key] = str_replace("'","",$value);
	$_POST[$key] = str_replace('"','',$value);
}
</pre>
<h3><strong>Guardar contrase&ntilde;as, n&uacute;meros de tarjeta de cr&eacute;dito, direcci&oacute;n de correo, etc. de forma segura con MD5 &oacute; SHA1</strong></h3>
<p>Para guardar las contrase&ntilde;as de los usuarios en las bases de datos debemos guardarlas de manera que no puedan ser visibles a simple vista ya que si alguna persona malintencionada consiguiera acceder a la base de datos, adem&aacute;s de conseguir el control de nuestra web, adem&aacute;s tendr&aacute; acceso a informaci&oacute;n sensible de los usuarios que nos visitan.</p>
<p>Para ello podemos dificultarlo mediante los res&uacute;menes <em>hash</em> MD5 o SHA-1, que aunque se tratan de  algoritmos <em>crackeados</em>, por lo menos no mostraremos como texto plano esta informaci&oacute;n.</p>
<p>Ejemplo:</p>
<pre class="code php">$a = "clave_pruebas";

echo "clave original: ".$a." ";

$b = md5($a);

echo "Hash MD5 de la clave original: ".$b." ";

$c = sha1($a);

echo "Hash SHA-1 de la clave original: ".$c." ";
</pre>
<p>Como podemos ver, con ello conseguimos ocultar m&iacute;nimamente la contrase&ntilde;a de cada usuario. Cuando un usuario se identifique con su contrase&ntilde;a, realizaremos el c&aacute;lculo del <em>hash</em> de su contrase&ntilde;a y compararemos contra la base de datos, no el texto plano de la contrase&ntilde;a, si no del <em>hash</em>.</p>
<h3>Uso de variables de sesi&oacute;n y no de <em>cookies</em></h3>
<p>Normalmente, alguna zona de nuestra web necesite acceso mediante usuario y contrase&ntilde;a. Para que el usuario no tenga que introducirlas repetidamente podemos guardarla mediante <em>cookies</em> pero es una pr&aacute;ctica muy insegura ya que si lo hici&eacute;ramos, esta informaci&oacute;n es transmitida mediante la red en texto plano y podr&iacute;a ser le&iacute;da por cualquier persona que realice un <em>sniffing</em> de red o que lea las <em>cookies</em> guardadas en nuestro ordenador mediante un virus o troyano.</p>
<p>Por ello lo mejor es hacer uso de las variables de sesi&oacute;n. Estas variables se guardan en el servidor por lo que en cualquier caso, la informaci&oacute;n transmitida s&oacute;lo es sensible la primera vez que se env&iacute;a y no las sucesivas veces (por tanto esto ser&iacute;a evitable haciendo uso del protocolo HTTPS en vez de HTTP).</p>
<p>Como ejemplo del usuario de variables de sesi&oacute;n, haremos uso de dos archivos. En el primero creamos una variable de sesi&oacute;n:</p>
<pre class="code php">session_start();
$_SESSION['clave'] = "clave_pruebas";
</pre>
<p>y en el segundo mostramos el valor en pantalla.</p>
<pre class="code php">session_start();
echo $_SESSION['clave'];
</pre>
<h3>Suplantaci&oacute;n de sesiones (<em>Session hijacking</em> o <em>Man in the middle</em>)</h3>
<p>Del uso de variables de sesi&oacute;n se deriva otra posible brecha de seguridad que es una persona malintencionada intente suplantar el cliente de cara al servidor. Cuando iniciamos una sesi&oacute;n, creamos una <em>cookie</em> con un identificador &uacute;nico para esa sesi&oacute;n. Si una persona malintencionada interceptase ese identificador &uacute;nico y mandase esa <em>cookie</em> al servidor, podr&iacute;a suplantar nuestra identidad y tener acceso a nuestras zonas restringidas de la web.</p>
<p>Lo soluci&oacute;n ideal ser&iacute;a el uso del protocolo HTTPS que encriptar&iacute;a toda nuestra conexi&oacute;n, pero si esto no es posible,  podemos crear una serie de comprobaciones en las que intentemos asegurarnos de la real identidad de cada usuario.</p>
<p>Para ello podemos guardar una serie de variables de sesi&oacute;n de los datos que el usuario nos proporciona en cada visita, como son la direcci&oacute;n IP o la informaci&oacute;n de su navegador, etc. Si estos cambian significar&iacute;a que es un intento de <em>session hijacking</em> y por tanto es un usuario que realiza un ataque. En el siguiente ejemplo tenemos dos archivos, en el que en el primer archivo realizamos un login satisfactorio y guardamos los datos iniciales de direcci&oacute;n IP y tipo del navegador con el que lo hemos hecho:</p>
<pre class="code php">session_start();
$_SESSION['REMOTE_ADDR'] = $_SERVER['REMOTE_ADDR'];
$_SESSION['HTTP_USER_AGENT'] = $_SERVER['HTTP_USER_AGENT'];
</pre>
<p>En pantallas posteriores, comprobaremos si en cada pantalla los datos actuales de direcci&oacute;n IP y datos del navegador se corresponden con los que se realiz&oacute; el login como usuario en la web:</p>
<pre class="code php">session_start();
if($_SESSION['REMOTE_ADDR'] != $_SERVER['REMOTE_ADDR'] || $_SESSION['HTTP_USER_AGENT'] != $_SERVER['HTTP_USER_AGENT']) {
	exit();
}
</pre>
<h3>Par&aacute;metros GET/POST explotables</h3>
<p>Para finalizar, si hacemos uso de par&aacute;metros GET y POST deberemos comprobar siempre que se correspondan con el usuario actual o si tiene permisos.</p>
<p>Por ejemplo, si tenemos un archivo que edita productos llamado editarProducto.php y recibe el par&aacute;metro GET idproducto, que se corresponde con el identificador &uacute;nico del producto a editar y llamamos al archivo de la siguiente manera:</p>
<pre class="code">http://www.miweb.com/editarProducto.php?idproducto=15</pre>
<p>deberemos comprobar en cualquier caso que en primer lugar seamos un usuario registrado y <em>logueado</em> y despu&eacute;s que el producto de identificador &uacute;nico 15 corresponde a uno de los productos del usuario <em>logueado</em>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=29</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/seguridad-en-php-basica-escribiendo-aplicaciones-web-seguras.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Un editor de textos web: TinyMCE</title>
			<link>http://www.imaginanet.com/blog/un-editor-de-textos-web-tinymce.html</link>
			<guid>http://www.imaginanet.com/blog/un-editor-de-textos-web-tinymce.html</guid>
			<comments>http://www.imaginanet.com/blog/un-editor-de-textos-web-tinymce.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Tue, 23 Mar 2010 12:00:45 +0100</pubDate>
					<category><![CDATA[JavaScript]]></category>
					<description><![CDATA[TinyMCE es una aplicaci&oacute;n escrita en Javascript que nos permite crear un editor de textos en nuestra web con una gran variedad de personalizaci&oacute;n y con caracter&iacute;sticas (que lo hacen interesante para usarlo en sistemas de gesti&oacute;n de contenido web), como pueden ser: 

Open Source
Ligero de peso
Ampliable...]]></description>
			<content:encoded><![CDATA[>TinyMCE es una aplicaci&oacute;n escrita en Javascript que nos permite crear un editor de textos en nuestra web con una gran variedad de personalizaci&oacute;n y con caracter&iacute;sticas (que lo hacen interesante para usarlo en <a title="imaginaCMS, sistema de gesti&oacute;n de contenido web a medida" href="/programacion-web/gestor-de-contenidos-web.html">sistemas de gesti&oacute;n de contenido web</a>), como pueden ser:<br /> 
<ul>
<li>Open Source</li>
<li>Ligero de peso</li>
<li>Ampliable mediante plugins</li>
<li>Usable en todos los navegadores.</li>
</ul>
En nuestro caso, vamos a configurarlo de tal manera que tenga el aspecto de un editor de textos simple cubriendo las funcionalidades b&aacute;sicas del editor.<br /><br />El primer paso ser&aacute; descargarlo de la <a title="editor de textos web" href="http://tinymce.moxiecode.com/" target="_blank">web oficial</a> y descomprimirlo en el disco duro. Crearemos un archivo de extensi&oacute;n html en la carpeta descomprimida con el siguiente c&oacute;digo:<br />
<pre class="code">&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
&lt;head&gt;
&lt;title&gt;Ejemplo de un editor de textos Web simple con TinyMCE&lt;/title&gt;

&lt;!-- TinyMCE --&gt;

&lt;script type="text/javascript" src="jscripts/tiny_mce/tiny_mce.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript"&gt;
	tinyMCE.init({
		mode : "exact",
		elements : "editor_texto",
		theme : "advanced",
		theme_advanced_buttons1:"bold,italic,underline,|,undo,redo,|,bullist,numlist",
		theme_advanced_buttons2:"",
		theme_advanced_buttons3:""

	});
&lt;/script&gt;
&lt;!-- /TinyMCE --&gt;

&lt;/head&gt;
&lt;body&gt;

&lt;h3&gt;Editor de textos Web&lt;/h3&gt;

&lt;textarea id="editor_texto" name="editor_texto" style="width: 30%;"&gt;Texto de prueba&lt;/textarea&gt;

&lt;/body&gt;
&lt;/html&gt;
</pre>
Si visualizamos el archivo en cualquier navegador web, podemos observar que tenemos un editor de textos que podemos usar en nuestra p&aacute;gina web. A continuaci&oacute;n explicaremos las opciones de configuraci&oacute;n que hemos usado:<br /> 
<ul>
<li><strong>mode "exact"</strong> y <strong>elements "editor_texto"</strong>: con estas dos l&iacute;neas indicamos que queremos aplicar el editor de textos s&oacute;lo al elemento de la web de identificador editor_texto</li>
<li><strong>theme "advanced"</strong>: elegimos utilizar el tema avanzado del editor para poder seleccionar los botones concretos que queremos que aparezcan mediante <strong>theme_advanced_buttons1</strong>, <strong>theme_advanced_buttons2</strong> y <strong>theme_advanced_buttons3</strong> donde seleccionaremos dentro de las tres posibles filas de botones del editor, que botones aparecer&aacute;n. En este caso negrita, cursiva, subrayado, una separaci&oacute;n, deshacer, rehacer, una separaci&oacute;n, lista y lista numerada respectivamente.</li>
</ul>
<br />]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=28</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/un-editor-de-textos-web-tinymce.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Cómo utilizar PayPal para realizar compras en tu web</title>
			<link>http://www.imaginanet.com/blog/como-utilizar-paypal-para-realizar-compras-en-tu-web.html</link>
			<guid>http://www.imaginanet.com/blog/como-utilizar-paypal-para-realizar-compras-en-tu-web.html</guid>
			<comments>http://www.imaginanet.com/blog/como-utilizar-paypal-para-realizar-compras-en-tu-web.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Wed, 17 Feb 2010 09:32:57 +0100</pubDate>
					<category><![CDATA[Comercio electrónico]]></category>
					<description><![CDATA[Vamos a explicar c&oacute;mo llamar al API de PayPal para realizar pagos en tu p&aacute;gina web. En primer lugar deberemos crear una cuenta como desarrollador de PayPal Sandbox (https://developer.paypal.com/) que usaremos para verificar que lo hacemos de manera correcta antes de hacerlo funcionar en la tienda virtual de nuestra...]]></description>
			<content:encoded><![CDATA[><p>Vamos a explicar c&oacute;mo llamar al <strong>API de PayPal</strong> para realizar pagos en tu p&aacute;gina web. En primer lugar deberemos crear una cuenta como desarrollador de <strong>PayPal Sandbox</strong> (<a href="https://developer.paypal.com/">https://developer.paypal.com/</a>) que usaremos para verificar que lo hacemos de manera correcta antes de hacerlo funcionar en la <a title="Desarrollo de aplicaciones e-commerce a medida" href="/diseno-web/tiendas-virtuales.html">tienda virtual</a> de nuestra p&aacute;gina web.</p>
<p>Tras hacerla y meternos en nuestra cuenta de desarrollador, deberemos seleccionar la opci&oacute;n <em>Create a preconfigured buyer or seller account</em> donde rellenaremos con nuestros datos el formulario teniendo en cuenta que debe ser una cuenta de vendedor.</p>
<p>Una vez creada, entraremos a nuestro listado de cuentas de PayPal Sandbox. Estas cuentas no son cuentas reales de PayPal y s&oacute;lo funcionar&aacute;n dentro de su Sandbox. Para entrar en ella pulsaremos el bot&oacute;n de <em>Enter Sandbox Test Site</em> y podremos introducir el usuario y contrase&ntilde;a para esta cuenta de prueba. Una vez dentro podemos observar que es como si fuera una cuenta de PayPal  pero los pagos que se hagan a ella no ser&aacute;n reales.</p>
<h4>Ejemplo de pago con el API de PayPal</h4>
<p>Para realizar el pago utilizaremos un documento HTML en el que le pasaremos los par&aacute;metros que PayPal necesita (importe, c&oacute;digo de venta, etc.) y otros opcionales como los datos del usuario que compra para que le aparezcan rellenados en el formulario de pago. Un ejemplo ser&iacute;a el siguiente:</p>
<pre class="code">&lt;html&gt;

&lt;head&gt;

&lt;title&gt;Ejemplo de pago mediante la API de PayPal&lt;/title&gt;

&lt;/head&gt;

&lt;body&gt;

&lt;form name='formTpv' method='post' action='https://www.sandbox.paypal.com/cgi-bin/webscr'&gt;

	&lt;input type='hidden' name='cmd' value='_xclick'&gt;
	&lt;input type='hidden' name='business' value='mi_cuenta_sandbox@mi_pagina.com'&gt;
	&lt;input type='hidden' name='item_name' value='Nueva compra en mi web'&gt;
	&lt;input type='hidden' name='item_number' value='VENTA-X2561'&gt;
	&lt;input type='hidden' name='amount' value='10.15'&gt;
	&lt;input type='hidden' name='page_style' value='primary'&gt;
	&lt;input type='hidden' name='no_shipping' value='1'&gt;
	&lt;input type='hidden' name='return' value='http://mi_pagina/exito.html'&gt;
	&lt;input type='hidden' name='rm' value='2'&gt;
	&lt;input type='hidden' name='cancel_return' value='http://mi_pagina/cancelada.html'&gt;
	&lt;input type='hidden' name='no_note' value='1'&gt;
	&lt;input type='hidden' name='currency_code' value='EUR'&gt;
	&lt;input type='hidden' name='cn' value='PP-BuyNowBF'&gt;
	&lt;input type='hidden' name='custom' value=''&gt;
	&lt;input type='hidden' name='first_name' value='NOMBRE'&gt;
	&lt;input type='hidden' name='last_name' value='APELLIDOS'&gt;
	&lt;input type='hidden' name='address1' value='DIRECCI&Oacute;N'&gt;
	&lt;input type='hidden' name='city' value='POBLACI&Oacute;N'&gt;
	&lt;input type='hidden' name='zip' value='C&Oacute;DIGO POSTAL'&gt;
	&lt;input type='hidden' name='night_phone_a' value=''&gt;
	&lt;input type='hidden' name='night_phone_b' value='TEL&Eacute;FONO'&gt;
	&lt;input type='hidden' name='night_phone_c' value=''&gt;
	&lt;input type='hidden' name='lc' value='es'&gt;
	&lt;input type='hidden' name='country' value='ES'&gt;
&lt;/form&gt;
&lt;script type='text/javascript'&gt;
	document.formTpv.submit();
&lt;/script&gt;

&lt;/body&gt;

&lt;/html&gt;
</pre>
<p>La direcci&oacute;n de llamada del formulario de pruebas es <span style="text-decoration: underline;">https://www.sandbox.paypal.com/cgi-bin/webscr</span> pero al pasar a ventas reales deberemos indicar <span style="text-decoration: underline;">https://www.paypal.com/cgi-bin/webscr</span></p>
<p>Como podemos ver, existente multitud de par&aacute;metros en el formulario que son f&aacute;ciles de ver cuales son su prop&oacute;sito (nombre, direcci&oacute;n, etc.). A continuaci&oacute;n detallamos los m&aacute;s importantes o que podemos tener duda de qu&eacute; son realmente:</p>
<ul>
<li><strong>business:</strong> indicaremos la cuenta de PayPal asociada al vendedor. Mientras estemos de pruebas indicaremos la cuenta de pruebas del Sandbox, pero para ventas reales deberemos indicar nuestra cuenta de vendedor.</li>
<li><strong>item_name:</strong> t&iacute;tulo que aparecer&aacute; en la pantalla de pago.</li>
<li><strong>item_number:</strong> c&oacute;digo de la venta, actuar&aacute; como identificador &uacute;nico de cada venta.</li>
<li><strong>amount:</strong> importe a pagar, donde si hay decimales no podr&aacute;n indicarse con una coma ni con m&aacute;s de dos n&uacute;meros.</li>
<li><strong>return:</strong> p&aacute;gina de vuelta a nuestra web indicando &eacute;xito en el pago.</li>
<li><strong>cancel_return:</strong> p&aacute;gina de vuelta a nuestra web indicando que no se realiz&oacute; el pago por que el usuario lo cancel&oacute;.</li>
<li><strong>currency_code:</strong> c&oacute;digo de la moneda usada en el pago. Para el caso del euro es EUR.</li>
<li><strong>lc:</strong> idioma de la pantalla de pago.</li>
<li><strong>country:</strong> c&oacute;digo ISO del pa&iacute;s del cliente.</li>
</ul>
<h3>Art&iacute;culos relacionados</h3>
<ul>
<li><a title="Pagos y transferencias masivas con PayPal" href="http://www.imaginanet.com/blog/pagos-en-serie-de-paypal.html">Pagos en serie de PayPal</a></li>
<li><a title="PayPal Instant Payment Notification" href="http://www.imaginanet.com/blog/controlar-los-pagos-por-paypal-mediante-notificacion-de-pago-instantanea.html">Controlar los pagos por PayPal mediante Notificaci&oacute;n de Pago Instant&aacute;nea</a></li>
</ul>
<ul>
</ul>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=27</wfw:commentRss>
			<slash:comments>20</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/como-utilizar-paypal-para-realizar-compras-en-tu-web.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Usando AJAX: Un simple ejemplo con PHP y jQuery.</title>
			<link>http://www.imaginanet.com/blog/usando-ajax-un-simple-ejemplo-con-php-y-jquery.html</link>
			<guid>http://www.imaginanet.com/blog/usando-ajax-un-simple-ejemplo-con-php-y-jquery.html</guid>
			<comments>http://www.imaginanet.com/blog/usando-ajax-un-simple-ejemplo-con-php-y-jquery.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Wed, 10 Feb 2010 10:48:36 +0100</pubDate>
					<category><![CDATA[jQuery]]></category>
					<category><![CDATA[Ajax]]></category>
					<description><![CDATA[Descrito de una manera muy resumida, AJAX es una tecnolog&iacute;a que nos permite realizar acciones en una p&aacute;gina web que necesiten respuesta del servidor sin recargarla. Con ello conseguimos que nuestra web sea din&aacute;mica y por tanto obtener un dise&ntilde;o m&aacute;s atractivo. Algunos ejemplos de lo que podemos...]]></description>
			<content:encoded><![CDATA[>Descrito de una manera muy resumida, <a href="http://es.wikipedia.org/wiki/AJAX">AJAX</a> es una tecnolog&iacute;a que nos permite realizar acciones en una p&aacute;gina web que necesiten respuesta del servidor sin recargarla. Con ello conseguimos que nuestra web sea din&aacute;mica y por tanto obtener un dise&ntilde;o m&aacute;s atractivo. Algunos ejemplos de lo que podemos hacer:                 
<ul>
<li>Un enlace que compruebe si un valor existe ya en una base de datos.</li>
<li>Completar un campo de texto de b&uacute;squeda con valores sugeridos por nuestra web.</li>
<li>Un chat web</li>
<li>etc.</li>
</ul>
<p>En este art&iacute;culo vamos a describir como realizar una sencilla llamada AJAX a una fichero externo que ejecutar&aacute; un proceso (una suma entre dos valores enviados mediante POST) y nos devolver&aacute; la salida correspondiente apoy&aacute;ndonos con la librer&iacute;a <a href="http://jquery.com/">jQuery</a>, que aunque no es necesario su uso, lo haremos sobre ella para aprovechar la potencia que nos proporciona. Se podr&iacute;a decir que es el t&iacute;pico <em>Hola mundo</em> en AJAX.</p>
<p>El c&oacute;digo se compone de dos archivos: un archivo donde mostraremos los formularios con datos de entrada y otro con el archivo de procesamiento.</p>
<p>A continuaci&oacute;n mostramos el c&oacute;digo del fichero de entrada de datos (habr&aacute; que tener cuidado con escribir correctamente la ruta a la librer&iacute;a jQuery):</p>
<pre class="code">&lt;html&gt;

&lt;head&gt;

&lt;title&gt;Ejemplo sencillo de AJAX&lt;/title&gt;

&lt;script type="text/javascript" src="/js/jquery.js"&gt;&lt;/script&gt;

&lt;script&gt;
function realizaProceso(valorCaja1, valorCaja2){
        var parametros = {
                "valorCaja1" : valorCaja1,
                "valorCaja2" : valorCaja2
        };
        $.ajax({
                data:  parametros,
                url:   'ejemplo_ajax_proceso.php',
                type:  'post',
                beforeSend: function () {
                        $("#resultado").html("Procesando, espere por favor...");
                },
                success:  function (response) {
                        $("#resultado").html(response);
                }
        });
}
&lt;/script&gt;

&lt;/head&gt;

&lt;body&gt;

Introduce valor 1

&lt;input type="text" name="caja_texto" id="valor1" value="0"/&gt; 


Introduce valor 2

&lt;input type="text" name="caja_texto" id="valor2" value="0"/&gt;

Realiza suma

&lt;input type="button" href="javascript:;" onclick="realizaProceso($('#valor1').val(), $('#valor2').val());return false;" value="Calcula"/&gt;

&lt;br/&gt;

Resultado: &lt;span id="resultado"&gt;0&lt;/span&gt;

&lt;/body&gt;

&lt;/html&gt;

</pre>
<p>&nbsp;</p>
<p>En este c&oacute;digo, utilizamos los id de las cajas de texto para pasarle sus valores a la funci&oacute;n <em>realizaProceso</em>. En esta funci&oacute;n recogemos los valores de entrada en un array parametros y enviamos mediante AJAX especificando el par&aacute;metro <em>data</em> (datos que mandamos), <em>url</em> (direcci&oacute;n del archivo de proceso) y <em>type</em> (POST o GET).</p>
<p>Por &uacute;ltimo vemos que tenemos dos eventos: <em>beforeSend</em> y <em>success</em> donde podemos indicar la acci&oacute;n a realizar mientras se procesan los datos y tras terminar de procesarlos (en este caso jugar con el contenido HTML del id resultado).</p>
<p>Ahora vemos el archivo de procesamiento de datos (<em>ejemplo_ajax_proceso.php</em>) que &uacute;nicamente suma los datos recibidos por POST:</p>
<pre class="code php">
&lt;?php 
$resultado = $_POST['valorCaja1'] + $_POST['valorCaja2']; 
echo $resultado;
?&gt;
</pre>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=26</wfw:commentRss>
			<slash:comments>2</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/usando-ajax-un-simple-ejemplo-con-php-y-jquery.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Crear plugins de jquery</title>
			<link>http://www.imaginanet.com/blog/plugins-jquery.html</link>
			<guid>http://www.imaginanet.com/blog/plugins-jquery.html</guid>
			<comments>http://www.imaginanet.com/blog/plugins-jquery.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Sat,  6 Feb 2010 21:09:29 +0100</pubDate>
					<category><![CDATA[JavaScript]]></category>
					<category><![CDATA[jQuery]]></category>
					<description><![CDATA[Jquery es una de las bibliocas javascript m&aacute;s simples e utilizadas. Crear plugins para esta biblioteca es muy sencillo. Vamos a ver los pasos necesarios: 

Primero tenemos que incluir la biblioteca jquery en la cabecera. Nos la descargamos desde su web y la a&ntilde;adimos de la siguiente forma:
			
		


Luego creamos...]]></description>
			<content:encoded><![CDATA[><a href="http://www.jquery.com" target="_blank">Jquery</a> es una de las bibliocas javascript m&aacute;s simples e utilizadas. Crear plugins para esta biblioteca es muy sencillo. Vamos a ver los pasos necesarios:<br /><br /> 
<ul>
<li>Primero tenemos que incluir la biblioteca jquery en la cabecera. Nos la descargamos desde su web y la a&ntilde;adimos de la siguiente forma:<br />
<pre class="code">			<script src="/ruta_a_jquery/jquery.js" type="text/javascript"></script>
		</pre>
</li>
<li>
<p>Luego creamos nuestro archivo del plugin, que luego tambi&eacute;n tendremos que a&ntilde;adirlo en la cabecera para utilizarlo.</p>
<pre class="code">			$.fn.duplicar = function () {
				this.each(function () {
					var html = "<br />"+$(this).html();
					$(this).append(html);
				});
			}
		</pre>
<p>Lo que hace este plugin es duplicar el contenido de los elementos seleccionados.<br /> $.fn es el objeto de jquery que contiene las funciones que nosotros le definimos. Dentro del c&oacute;digo de la funci&oacute;n, el this es un array con los elementos seleccionados con jquery. Con la funci&oacute;n each, recorremos ese array.</p>
</li>
<li> Para utilizarlo:
<pre class="code">			$("div.doble").duplicar();
		</pre>
<p>As&iacute; duplicar&iacute;amos el contenido de todos los divs con la clase "doble"</p>
</li>
</ul>
<p>&Eacute;ste es un ejemplo muy b&aacute;sico. Para m&aacute;s informaci&oacute;n s&oacute;lo hay que pasarse por la web de jquery la cual tiene una bastante buena <a href="http://docs.jquery.com/Main_Page" target="_blank">documentaci&oacute;n</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=25</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/plugins-jquery.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Display inline-block e internet explorer.</title>
			<link>http://www.imaginanet.com/blog/display-inline-block-e-internet-explorer.html</link>
			<guid>http://www.imaginanet.com/blog/display-inline-block-e-internet-explorer.html</guid>
			<comments>http://www.imaginanet.com/blog/display-inline-block-e-internet-explorer.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Sat,  6 Feb 2010 19:41:50 +0100</pubDate>
					<category><![CDATA[XHTML]]></category>
					<category><![CDATA[CSS]]></category>
					<category><![CDATA[Internet Explorer]]></category>
					<category><![CDATA[Navegadores]]></category>
					<description><![CDATA[La propiedad display de css (en la versi&oacute;n 2.1), puede contener un valor muy interesante, inline-block. Con este valor conseguimos que el elemento con esa propiedad se comporte como una caja, pero mostrandose en la misma l&iacute;nea, como si tuviese display: inline.
&iquest;Y esto de qu&eacute; nos sirve?, pues si no...]]></description>
			<content:encoded><![CDATA[><p>La propiedad display de css (en la versi&oacute;n 2.1), puede contener un valor muy interesante, <strong>inline-block</strong>. Con este valor conseguimos que el elemento con esa propiedad se comporte como una caja, pero mostrandose en la misma l&iacute;nea, como si tuviese display: inline.</p>
<p>&iquest;Y esto de qu&eacute; nos sirve?, pues si no usamos esta propiedad tendr&iacute;amos que a&ntilde;adirle a la caja un "float: left", por ejemplo, pero esto trae unas consecuencias, a veces, muy molestas. Por ejemplo, si queremos mostrar contenido dividido en cajas y que se muestren filas de 3 cajas, si &eacute;stas var&iacute;an con la altura, pasar&iacute;a esto:</p>
<img src="http://www.imaginanet.com/blog_files/inline-block/confloat.png" alt="con float" />
<p>Esto pasa porque al tener "float:left", las cajas "buscan" el primer espacio disponible a su izquierda. &Eacute;sto podr&iacute;a solucionarse desde el html, a&ntilde;adiendo cada tres cajas un elemento que tenga la propiedad "clear:both". Pero si queremos que el n&uacute;mero de cajas por fila var&iacute;e dependiendo de la anchura de nuestra ventana del navegador, ya no valdr&iacute;a esta soluci&oacute;n. Adem&aacute;s si usamos la propiedad "display: inline-block", podemos alinear las cajas arriba, abajo, al centro , con tan solo cambiar la propiedad vertical-align. Si ponemos "vertical-align:top", tendremos esto:</p>
<img src="http://www.imaginanet.com/blog_files/inline-block/deseable.png" alt="con float" />
<h2>Hacks para conseguir "display: inline-block" en internet explorer 6 y 7</h2>
<p>Nuestros amigos Ie6 e Ie7, como siempre, mostrandonos su tecnolog&iacute;a punta (recordemos que &eacute;sto es CSS 2.1), no implementan esta propiedad completamente.</p>
<p>De todas formas es muy sencillo hacerlo funcionar con un peque&ntilde;o truco. En vez de usar "display: inline-block", tendr&iacute;amos que ponerles "display: inline" y a&ntilde;adirles la propiedad "zoom:1"</p>
<pre class="code">	div.block {
		display: inline-block;
		#display: inline-block;
		_display: inline;
		zoom: 1;
	}
</pre>
<p>La "#" es un hack para que solo aplique esa propiedad IE7 y el "_" para IE6. La propiedad zoom solo la cojeran esos 2 navegadores, puesto que no es est&aacute;ndar, haciendo que el elemento se comporte como una caja.</p>
<a href="http://www.imaginanet.com/blog_files/inline-block/inline-block.htm" target="_blank">Ver ejemplo en funcionamiento.</a><br /> <a href="http://www.imaginanet.com/blog_files/inline-block/inline-block.htm" target="_blank"><img src="http://www.imaginanet.com/blog_files/inline-block/ejemplo.png" alt="con float" /></a>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=24</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/display-inline-block-e-internet-explorer.html</feedburner:origLink>
		</item>
				
		<item>
			<title>HTML 5 y el famoso tag "video"</title>
			<link>http://www.imaginanet.com/blog/html-5-y-el-famoso-tag-video.html</link>
			<guid>http://www.imaginanet.com/blog/html-5-y-el-famoso-tag-video.html</guid>
			<comments>http://www.imaginanet.com/blog/html-5-y-el-famoso-tag-video.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Thu, 28 Jan 2010 08:27:06 +0100</pubDate>
					<category><![CDATA[HTML5]]></category>
					<category><![CDATA[Navegadores]]></category>
					<description><![CDATA[HTML5 ha llegado, y aunque sea pronto para que el usuario pueda disfrutar de todo su potencial, los programadores hace ya unos meses que podemos ir viendo como ser&aacute;n las webs de dentro de unos a&ntilde;os. El tag &lt;video/&gt; es el que m&aacute;s revuelo est&aacute; teniendo, y no solo por su integraci&oacute;n en sitios...]]></description>
			<content:encoded><![CDATA[>HTML5 ha llegado, y aunque sea pronto para que el usuario pueda disfrutar de todo su potencial, los programadores hace ya unos meses que podemos ir viendo como ser&aacute;n las webs de dentro de unos a&ntilde;os.<br /><br /> El tag &lt;video/&gt; es el que m&aacute;s revuelo est&aacute; teniendo, y no solo por su integraci&oacute;n en sitios como Youtube o Vimeo, sin&oacute; por los est&aacute;ndares soportados por cada navegador.<br /><br /> Mozilla se ha puesto firme al respecto y ha anunciado que no piensa incluir el estandar h264, ya que este no es un codec abierto y existen otros que si lo son y pueden ofrecer mejor calidad.<br /> Esto nos deja en una situaci&oacute;n en la que los navegadores web que actualmente soportan el tag  de HTML5:<br /><br /> &bull;Presto/Opera: HTML5 mediante GStreamer (incluye s&oacute;lo Ogg/Theora).<br /> &bull;WebKit/Chrome: HTML5 mediante ffmpeg (Ogg/Theora y H.264/MP4).<br /> &bull;Gecko/Firefox: HTML5 con Ogg/Theora.<br /> &bull;WebKit/Epiphany: HTML5 mediante GStreamer (Ogg/Theora garantizado).<br /> &bull;WebKit/Safari: HTML5 mediante QuickTime (H.264/MOV/M4V, puede reproducir Ogg/Theora con XiphQT components).<br /><br /> Nos encontramos frente a una guerra en la que empresas como Apple y Microsoft, forman parte de la MPEG-LA, empresa que tiene la patente del codec h264, frente a Mozilla (por el momento) que se ha posicionado en contra de usar una tecnolog&iacute;a propietaria que condicione la red.<br /><br />Por su parte, Youtube no da su brazo a torcer. A pesar de que hay decenas de peticiones y de comentarios pidiendo el soporte de Ogg Theora, no sueltan prenda al respecto.]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=23</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/html-5-y-el-famoso-tag-video.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Menú desplegable con CSS</title>
			<link>http://www.imaginanet.com/blog/menu-desplegable-con-css.html</link>
			<guid>http://www.imaginanet.com/blog/menu-desplegable-con-css.html</guid>
			<comments>http://www.imaginanet.com/blog/menu-desplegable-con-css.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Mon, 28 Dec 2009 18:28:03 +0100</pubDate>
					<category><![CDATA[XHTML]]></category>
					<category><![CDATA[CSS]]></category>
					<description><![CDATA[Vamos a crear un men&uacute; desplegable utilizando &uacute;nicamente CSS. En principio no necesitaremos nada de javascript. Este men&uacute; funcionar&aacute; en las &uacute;ltimas versiones de firefox, chrome, safari, opera, e internet explorer (versi&oacute;n 8). Para que funcione en Internet explorer 7 s&oacute;lo...]]></description>
			<content:encoded><![CDATA[>Vamos a crear un men&uacute; desplegable utilizando &uacute;nicamente <a href="/diseno-web/desarrollo-web/maquetacion-html-css.html" target="_blank">CSS</a>. En principio no necesitaremos nada de javascript. Este men&uacute; funcionar&aacute; en las &uacute;ltimas versiones de firefox, chrome, safari, opera, e internet explorer (versi&oacute;n 8). Para que funcione en Internet explorer 7 s&oacute;lo necesitaremos a&ntilde;adir unos peque&ntilde;os <a href="#hacks">hacks</a>. En explorer 6 necesitaremos utilizar javascript, puesto que este navegador no reconoce el selector ":hover" en elementos que no sean "a", los cuales no pueden contener elementos de tipo bloque dentro, si queremos cumplir los est&aacute;ndares, claro. Al final se explican los <a href="#hacks">hacks necesarios</a>.<br /><br /> Para comenzar definimos la estructura del men&uacute;, bas&aacute;ndonos en listas desordenadas (ul, li):<br /><br />
<pre class="code"><ul class="menu">
	<li>
		<a class="item" href="#">Item 1</a>
		<ul>
			<li>
				<a class="item" href="#">Option 1</a>
			</li>
			<li>
				<a class="item" href="#">Option 2</a>
			</li>
		</ul>
	</li>
</ul>
</pre>
<br /> Cada li tendr&aacute; un "a" con clase "item", y si queremos a&ntilde;adirle un submen&uacute;, un "ul", en este caso le tendremos que a&ntilde;adir la clase more al "a" por cuesti&oacute;n de estilo, as&iacute; mostrar&aacute; una flecha a la derecha, indicando que hay un submen&uacute; oculto. <br /><br /> Ahora tenemos que ocultar los submen&uacute;s desde la hoja de estilos, para eso le a&ntilde;adimos la propiedad "display:none" a los "ul" dentro del "ul" principal: <br /><br />
<pre class="code">ul.menu {
	display: inline-block;
	margin: 0;
	padding: 0;
	list-style-type: none;
	white-space: nowrap;
}
ul.menu ul {
	display: none;
}
ul.menu li {
	position: relative;
	display: inline-block;
}
ul.menu ul li {
	display: block;
}
</pre>
<br /> A los li del primer nivel les aplicamos la propiedad "display: inline-block", para que se muesten en una sola l&iacute;nea, a los dem&aacute;s les ponemos "display:block". El primer ul tiene la propiedad "white-space: nowrap", para forzar a que sus "li" no salten de l&iacute;nea. Ahora ya tenemos los submen&uacute;s ocultos, falta hacerlos aparecer:<br /><br />
<pre class="code">ul.menu &gt; li:hover &gt; ul {
	display: block;
	position: absolute;
	top: 100%;
	left: 0;
}

ul.menu ul li:hover &gt; ul {
	display: block;
	position: absolute;
	top: 0;
	left: 100%;
}
</pre>
<br /> Los submen&uacute;s est&aacute;n posicionados absolutamente con respecto al "li" que los contiene, ya que &eacute;stos est&aacute;n posicionados relativamente. En el caso de los submen&uacute;s del primer nivel los colocamos con "top:100%,left:0", para que salgan justo debajo del item padre. Para los dem&aacute;s submen&uacute;s ponemos "top: 0; left: 100%", con lo que saldr&aacute;n justo a la derecha del item padre.<br /><br /> Al final nos quedar&aacute; algo parecido a esto:<br /><br />
<div><img title="men&uacute;" src="/blog_files/menu-css/captura.png" alt="men&uacute;" /></div>
<br /> <br /><strong></strong>
<h3><strong><a name="hacks"></a></strong>Hacks para Internet explorer 6 y 7:</h3>
<br /> <a href="/blog/display-inline-block-e-internet-explorer.html">En Internet explorer 6 y 7, no funciona la propiedad "display: inline-block" en elementos que tienen por defecto display: block</a>, pero con un sencillo truco podemos conseguir el mismo efecto:<br /><br />
<pre class="code">ul.menu li {
	position: relative;
	display: inline-block;
	_display: inline;
	_zoom: 1;
	#display: inline;
	#zoom: 1;
}
</pre>
<br /> Para hacer que los submen&uacute;s aparezcan en internet explorer 6, tendremos que utilizar javascript, como coment&aacute;bamos al principio. Utilizando la librer&iacute;a jquery, por ejemplo, har&iacute;amos lo siguiente:<br /><br />
<pre class="code">$("ul.submenu li").hover(
	function () {
		$(this).addClass("hover");
	},
	function () {
		$(this).removeClass("hover");
	}
);
</pre>
<br /> Como tampoco funciona el selector "&gt;" en IE6, necesitaremos hacer unos cambios en la hoja de estilos: <br /><br />
<pre class="code">ul.menu li.hover ul {
	display: block;
	position: absolute;
	top: 100%;
	left: 0;
}

ul.menu li.hover ul ul {
	display: none;
}

ul.menu ul li.hover ul {
	display: block;
	position: absolute;
	top: 0;
	left: 100%;
}

ul.menu ul li.hover ul ul {
	display: none;
}
</pre>
<br /> Para probar este men&uacute; accede <a href="/blog_files/menu-css/index.htm" target="&quot;_blank&quot;">aqu&iacute;</a>.<br /> Para descargarte los archivos utilizados haz click <a href="/blog_files/menu-css/menu-css.zip">aqu&iacute;</a>.<br />]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=22</wfw:commentRss>
			<slash:comments>3</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/menu-desplegable-con-css.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Creando un buscador para tu página usando Yahoo! Query Language</title>
			<link>http://www.imaginanet.com/blog/creando-un-buscador-para-tu-pagina-usando-yahoo-query-language.html</link>
			<guid>http://www.imaginanet.com/blog/creando-un-buscador-para-tu-pagina-usando-yahoo-query-language.html</guid>
			<comments>http://www.imaginanet.com/blog/creando-un-buscador-para-tu-pagina-usando-yahoo-query-language.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Thu, 24 Dec 2009 11:01:31 +0100</pubDate>
					<category><![CDATA[Buscadores]]></category>
					<description><![CDATA[Hace un par de semanas vi un vídeo tutorial en el que se muestra la potencia y la facilidad de uso de Yahoo! Query Language donde creando un código HTML y Javascript muy simple obtiene como respuesta (por cierto una respuesta muy rápida) la búsqueda en los buscadores de Yahoo!, Google y Bing. El vídeo en cuestión es el...]]></description>
			<content:encoded><![CDATA[><!-- 		@page { margin: 2cm } 		P { margin-bottom: 0.21cm } 		A:link { so-language: zxx } -->
<p style="margin-bottom: 0cm;">Hace un par de semanas vi un <a href="http://ajaxian.com/archives/three-search-engines-one-interface-25-minutes-live-code">vídeo tutorial</a> en el que se muestra la potencia y la facilidad de uso de <a href="http://developer.yahoo.com/yql/">Yahoo! Query Language</a> donde creando un código HTML y Javascript muy simple obtiene como respuesta (por cierto una respuesta muy rápida) la búsqueda en los buscadores de Yahoo!, Google y Bing. El vídeo en cuestión es el siguiente:</p>
<p style="margin-bottom: 0cm;"> </p>
<div>
<object width="400" height="275" data="http://vimeo.com/moogaloop.swf?clip_id=8075850&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=&fullscreen=1" type="application/x-shockwave-flash">
<param name="data" value="http://vimeo.com/moogaloop.swf?clip_id=8075850&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=&fullscreen=1" />
<param name="allowfullscreen" value="true" />
<param name="allowscriptaccess" value="always" />
<param name="src" value="http://vimeo.com/moogaloop.swf?clip_id=8075850&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=&fullscreen=1" />
</object>
</div>
<p><a href="http://vimeo.com/8075850">Building a search mashup with YQL using Google, Yahoo and Bing - live :)</a> from <a href="http://vimeo.com/user574521">Christian Heilmann</a> on <a href="http://vimeo.com">Vimeo</a>.</p>
<!-- 		@page { margin: 2cm } 		P { margin-bottom: 0.21cm } 		A:link { so-language: zxx } -->
<p style="margin-bottom: 0cm;">Tras verlo empecé a realizar pruebas con la <a href="http://developer.yahoo.com/yql/console/">consola de YQL</a> para ver que nos permite hacer esta API y realicé la primera consulta:</p>
<pre class="code">select * from search.web(20) where query="PHP";</pre>
Después probé a realizar la misma búsqueda en todos los buscadores:<br />
<pre class="code">select * from query.multi where queries='
  select *  from microsoft.bing.web(20) where query="PHP";
  select *  from search.web(20) where query="PHP";
  select *  from google.search(20) where q="PHP"
'
</pre>
<br />Lo más interesante, es que en la consola nos proporciona <a href="http://query.yahooapis.com/v1/public/yql?q=%09select%20*%20from%20query.multi%20where%20queries%3D'%0A%09%20%20select%20*%20%20from%20microsoft.bing.web(20)%20where%20query%3D%22PHP%22%3B%0A%09%20%20select%20*%20%20from%20search.web(20)%20where%20query%3D%22PHP%22%3B%0A%09%20%20select%20*%20%20from%20google.search(20)%20where%20q%3D%22PHP%22%0A'&format=xml&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys">la dirección para obtener esta consulta</a> y devuelve los datos en formato XML, por lo que hacer una aplicación que realice la llamada y obtenga la respuesta es realmente fácil de realizar.<br /><br />Tras buscar por la documentación no he encontrado ninguna opción de poder filtrar los resultados por país o idioma, por lo que habrá que esperar hasta que añadan esta característica y podamos realizarlas en otros idiomas.<br /><br /> Finalmente, viendo <a href="http://developer.yahoo.com/yql/guide/index.html">la documentación</a> observamos que tiene posibilidades muy variadas como añadir un post a tu blog Wordpress, interactuar con Flickr, con Yahoo! Maps, Amazon o Facebook entre otras, pudiendo usar YQL como API para estos servicios, por lo que es un servicio a tener en cuenta para integrarlo con otro uso que no sea el de realizar búsquedas.<br /><br /> <br />
<p style="margin-bottom: 0cm;"> </p>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=21</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/creando-un-buscador-para-tu-pagina-usando-yahoo-query-language.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Como usar Google Apps en tu web</title>
			<link>http://www.imaginanet.com/blog/como-usar-google-apps-en-tu-web.html</link>
			<guid>http://www.imaginanet.com/blog/como-usar-google-apps-en-tu-web.html</guid>
			<comments>http://www.imaginanet.com/blog/como-usar-google-apps-en-tu-web.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Thu, 24 Dec 2009 10:41:10 +0100</pubDate>
					<category><![CDATA[Google Apps]]></category>
					<description><![CDATA[Si alguna vez necesitas incluir google apps en tu dominio, aqui tienes una sencilla explicación de como puedes empezar.
1.Regístrate y accede a tu cuenta
En la página  principal de Google Apps, haz clic en "Comparar ediciones y registrarse"  para empezar a utilizar el programa y acceder al panel de  control.Más  información...]]></description>
			<content:encoded><![CDATA[>Si alguna vez necesitas incluir google apps en tu dominio, aqui tienes una sencilla explicación de como puedes empezar.<br /><br />
<h3 style="font-size: 1.17em;">1.Regístrate y accede a tu cuenta</h3>
En la <a href="http://www.google.com/a/help/intl/en/business/applications.html">página  principal de Google Apps</a>, haz clic en "Comparar ediciones y registrarse"  para empezar a utilizar el programa y acceder al panel de  control.<br /><br /><strong><a href="http://www.google.com/support/a/bin/answer.py?answer=107246">Más  información <br /></a></strong><br />
<h3 style="font-size: 1.17em;">2.Verifica la propiedad del dominio</h3>
Confirma que eres el propietario del dominio con el que te has registrado para  habilitar Google Apps.<br /><br />
<h3 style="font-size: 1.17em;">3.Personaliza Google Apps</h3>
Google Apps permite modificar fácilmente varias configuraciones para aplicarlas  a toda tu organización.<br /><br />
<h3 style="font-size: 1.17em;">4.Crea cuentas de usuario</h3>
En el panel de control, crea tantas cuentas de usuario como necesite tu  organización.<br /><br />
<h3 style="font-size: 1.17em;">5.Migrar datos y activa el correo electrónico</h3>
Configura los registros Mail Exchange (MX) de tu dominio para habilitar la  entrega de correo electrónico.<br /><br />
<h3 style="font-size: 1.17em;">6.Implanta Google Apps</h3>
Ahora que has creado cuentas de usuario y has activado los servicios, ha llegado  el momento de ayudar a tus usuarios para que empiecen a utilizar Google Apps.<br /><br />
<h3 style="font-size: 1.17em;">¿Cómo ver el correo de nuestra cuenta?</h3>
- Podemos usar las funciones de php imap. Aquí va un pequeño ejemplo de como sacar un listado de los últimos 7 mensajes de correo.<br /><br />
<pre class="code php">function fix_text($str)
{
    $subject = '';
    $subject_array = imap_mime_header_decode($str);

    foreach ($subject_array AS $obj)
        $subject .= rtrim($obj->text, "t");

    return $subject;
} 


$mail = imap_open('{imap.gmail.com:993/novalidate-cert/ssl}', 'cuenta de correo', 'contraseña de la cuenta');
$last = imap_num_msg($mail);

echo '&lt;strong&gt;&lt;a href=&quot;/url_dominio_google/?account_id=cuenta_de_correo&quot; target=&quot;_blank&quot;&gt;Mensajes de correo ('.$last.') / &lt;span style=&quot;color: #e71d02;&quot;&gt;Nuevos ('.$nuevos.')&lt;/span&gt;&lt;/a&gt;&lt;/strong&gt;';

if ($last>7) $ini=($last-7);
else $ini=1;

$nuevos=0;
for ($i=$last;$i>=$ini;$i--){
	$header = imap_header($mail, $i);
	$from=$header->from;
	if (is_array($from)){
	        $de=$from[0]->personal;
	}

	$asunto=fix_text($header->subject);
	$asunto='<span title="'.$asunto.'">'.$asunto."</span>";

	if ($header->Unseen=="U"){
		$de='<strong>'.$de.'</strong>';
		$asunto='<strong>'.$asunto."</strong>";
		$nuevos++;
	}
	echo '<span title="'.$from[0]->personal.'">'.$de.'</span> - '.$asunto.' '.date('d/m', $header->udate);
}

imap_close($mail);<br />
</pre>
En el ejemplo conectamos con la cuenta de correo con la contraseña y obtenemos los últimos 7 mensajes de correo.<br />Luego vamos sacando mensaje a mensaje con el formato html que más no interese.<br />La condición de la linea 32 es para saber si el mensaje ha sido visto por el usuario o todavía no.<br /><br />
<h3 style="font-size: 1.17em;">¿Cómo ver el google calendar?</h3>
Para esta opción hay que tener requerido en nuestro php las librerías de Zend que podemos descargar de la web http://www.zend.com<br />A continuación nos logueamos con nuestro usuario y contraseña de google apps y pedimos la información del tramo de fechas de google calendar que queremos obtener.<br />A continuación tenéis un ejemplo de como obtener los datos de google calendar del mes de enero de 2010<br /> 
<pre class="code php">require_once('Zend/Loader.php');
Zend_Loader::loadClass('Zend_Gdata');
Zend_Loader::loadClass('Zend_Gdata_AuthSub');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
Zend_Loader::loadClass('Zend_Gdata_Calendar');

$service = Zend_Gdata_Calendar::AUTH_SERVICE_NAME;
$client = Zend_Gdata_ClientLogin::getHttpClient('usuario google apps', 'contraseña', $service);
$service = new Zend_Gdata_Calendar($client);
$dominioGapps=explode('@','usuario google apps');

echo 'http://www.google.com/calendar/hosted/'.trim($dominioGapps[1]).'/render?account_id='.urlencode('usuario google apps');

$query = $service->newEventQuery();
$query->setUser('id del calendario'); //Tambien se puede poner la opcion 'default' para el calendario común

$query->setVisibility('private');
$query->setProjection('full');
$query->setOrderby('starttime');
//$query->setFutureevents('true');// Retrieve the event list from the calendar server
$query->setStartMin('2010-01-01');
$query->setStartMax('2010-01-30');
try {    
	$eventFeed = $service->getCalendarEventFeed($query);
} catch (Zend_Gdata_App_Exception $e) {
	echo "Error: " . $e->getResponse();
}

foreach ($eventFeed as $event) {
	$valor=$event->when;
	$donde=$event->where;
	$autor=$event->author;
	$categoria=$event->category;
	$idevento=$event->link;
	$diaEvento=$valor[0]->startTime;
	$diaMesEvento = intval(substr($diaEvento,8,2));
	$dias[$diaMesEvento] .= $event->title->text.". Hora: ".substr($diaEvento,11,5)." (".substr($diaEvento,23,6).")n";
	$enlaceEvento[$diaMesEvento]=$idevento[0]->href;
}
</pre>
En este ejemplo obtenemos un array con los eventos que hay por dia]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=20</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/como-usar-google-apps-en-tu-web.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Usando el API de Google Analytics para mejorar nuestra web</title>
			<link>http://www.imaginanet.com/blog/usando-el-api-de-google-analytics-para-mejorar-nuestra-web.html</link>
			<guid>http://www.imaginanet.com/blog/usando-el-api-de-google-analytics-para-mejorar-nuestra-web.html</guid>
			<comments>http://www.imaginanet.com/blog/usando-el-api-de-google-analytics-para-mejorar-nuestra-web.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Wed, 23 Dec 2009 16:11:32 +0100</pubDate>
					<category><![CDATA[Google Analytics]]></category>
					<category><![CDATA[SEO]]></category>
					<description><![CDATA[Desde que Google sac&oacute; su herramienta Analytics nos proporcion&oacute; una nueva perspectiva gratuita para ver nuestra web desde los ojos de las personas que la visitan permiti&eacute;ndonos conocer lo que "realmente opinan" los usuarios de tu web.
A primera vista desde el panel de control de Google Analytics, la gran...]]></description>
			<content:encoded><![CDATA[><p>Desde que Google sac&oacute; su herramienta <a href="http://www.google.com/analytics/">Analytics</a> nos proporcion&oacute; una nueva perspectiva gratuita para ver nuestra web desde los ojos de las personas que la visitan permiti&eacute;ndonos conocer lo que "realmente opinan" los usuarios de tu web.</p>
<p>A primera vista desde el panel de control de Google Analytics, la gran cantidad de opciones y men&uacute;s que tenemos resulta hasta confusa para entender realmente que nos est&aacute;n diciendo y m&aacute;s a&uacute;n para gente inexperta. As&iacute; que tras un tiempo trabajando con ella, decid&iacute; ponerme manos a la obra para simplificar esta gran herramienta para hacerla un poco m&aacute;s sencilla.</p>
<h3>&iquest;C&oacute;mo usar el API?</h3>
<p>En primer lugar, damos por supuesto que tenemos una cuenta de Google Analytics y un sitio web <a href="http://www.google.com/support/googleanalytics/bin/static.py?page=guide.cs&amp;guide=19779&amp;topic=19783">con el c&oacute;digo Javascript</a> que nos haga recolectar las estad&iacute;sticas en nuestra cuenta.</p>
<p>En segundo lugar deberemos elegir unas librer&iacute;as que nos ayuden a usar el API en funci&oacute;n del lenguaje de programaci&oacute;n que vayamos a usar. Para ello, podemos encontrar en la <a href="http://code.google.com/intl/es-ES/apis/analytics/docs/gdata/gdataLibraries.html">secci&oacute;n de librer&iacute;as de Google Analytics</a> una buena cantidad de librer&iacute;as para diferentes lenguajes (Java, Python, PHP, etc.).</p>
<p>Tras estos dos pasos iniciales, tenemos todo listo para empezar a utilizar el API. Podemos echar un vistazo a la <a href="http://code.google.com/intl/es-ES/apis/analytics/docs/gdata/gdataReferenceDimensionsMetrics.html">documentaci&oacute;n del API</a>&nbsp; y como era de esperar las posibilidades que nos ofrece esta complet&iacute;sima API son muchas.</p>
<p>Lo que m&aacute;s nos interesa es conocer los par&aacute;metros con los que podemos utilizarla: <strong>dimensiones</strong> qu&eacute; es lo que vamos a medir y las <strong>m&eacute;tricas</strong> son en qu&eacute; unidad lo vamos a medir. Estas dimensiones y m&eacute;tricas las podemos agrupar de la manera que queramos, aunque para obtener unos buenos resultados deberemos hacerlo con sentido y adem&aacute;s, podemos hacer el uso de <strong>filtros</strong>, que nos permite filtrar los valores devueltos por una m&eacute;trica o una dimensi&oacute;n (por ejemplo una direcci&oacute;n web en concreto).</p>
<p>A continuaci&oacute;n vamos a hablar de los datos b&aacute;sicos que se desprenden de su uso.</p>
<h3><strong>&iquest;Tiene buen contenido o dise&ntilde;o mi web?</strong></h3>
<p>Tras interpretar los datos que obtenemos, podemos considerar si nuestra web tiene buenos contenidos o no desde dos puntos de vista, globalmente o espec&iacute;ficamente para una p&aacute;gina determinada.</p>
<p><span style="text-decoration: underline;">Desde el punto de vista global</span>, deberemos prestar atenci&oacute;n al grupo de m&eacute;tricas <code>ga:bounces</code> y <code>ga:entrances</code> que nos dir&aacute; el tanto por cien de rebote de nuestra web. Este c&aacute;lculo lo haremos realizando la divisi&oacute;n de&nbsp; <code>ga:bounces</code> entre <code>ga:entrances</code> d&aacute;ndonos como resultado el n&uacute;mero de cuantas personas abandonan la web tras visitar nuestra p&aacute;gina inicial.</p>
<p>Un alto n&uacute;mero en el tanto por cien de rebotes nos indica que la p&aacute;gina inicial no contiene o no muestra de manera correcta lo que el usuario esperaba encontrar en ella y por tanto vuelve a la p&aacute;gina anterior por donde lleg&oacute;.</p>
<p>Otra valoraci&oacute;n que podemos hacer es si estos contenidos globales son interesantes o no para el usuario mediante la m&eacute;trica <code>ga:timeOnSite</code> que nos proporciona la cantidad de tiempo que estuvo el usuario en nuestra web y la dimensi&oacute;n <code>ga:pageDepth</code>, que nos dice la cantidad media que los usuarios ven cuando entran en nuestra web.</p>
<span style="text-decoration: underline;">Desde el punto de vista espec&iacute;fico para una determinada p&aacute;gina</span>, si existe un alto n&uacute;mero n&uacute;mero de rebotes significa que al llegar a esa p&aacute;gina es confusa o no tiene inter&eacute;s para el usuario as&iacute; que deber&iacute;amos mejorar los aspectos donde falle. Este c&aacute;lculo lo realizaremos realizando la divisi&oacute;n de las dimensiones <code>ga:bounces</code> entre <code>ga:uniquePageviews</code> a&ntilde;adiendo la dimensi&oacute;n <code>ga:pagePath</code> a la consulta.
<h3><strong>&iquest;Son buenas las palabras clave que utilizo para cada p&aacute;gina?</strong></h3>
<p>Las palabras claves nos sirven junto al contenido de cada p&aacute;gina para describirla de cara a los buscadores. Para ver si las palabras claves que describen nuestras p&aacute;ginas son buenas podemos utilizar las dimensiones <code>ga:source</code> filtrando por <code>ga:pagePath</code>, especificando en esta &uacute;ltima la p&aacute;gina deseada a comprobar.</p>
<p>Si el resultado que nos devuelve es alto desde los buscadores Google, Yahoo, Bing, etc. significa que de cara a los buscadores las palabras clave describen bien el contenido.</p>
<h3><strong>&iquest;Cu&aacute;l es el comportamiento de los visitantes de mi web?</strong></h3>
<p>Un valor interesante es el que nos proporciona la dimensi&oacute;n <code>ga:secondPagePath</code>, que nos dice cu&aacute;l fue la segunda p&aacute;gina que visit&oacute; el usuario tras ver nuestra web. &Eacute;sto nos indica que es lo que m&aacute;s llama la atenci&oacute;n en nuestra web pudiendo potenciar otras p&aacute;ginas que deber&iacute;an tener mejores resultados.</p>
<p>Podemos observar tambi&eacute;n la navegaci&oacute;n que realizan los usuarios para p&aacute;ginas determinadas y ver desde qu&eacute; p&aacute;gina llegaron y a qu&eacute; p&aacute;gina fueron desde ella. En este caso, para saber desde qu&eacute; p&aacute;gina llegaron a otra deberemos usar como par&aacute;metros la dimensi&oacute;n <code>ga:previousPagePath</code>,m&eacute;trica <code>ga:pageviews</code> y el filtro <code>ga:nextPagePath</code> especificando la p&aacute;gina objetivo.</p>
<p>Por el contrario, para saber qu&eacute; p&aacute;gina visitaron desde la actual usaremos la dimensi&oacute;n <code>ga:nextPagePath</code>, m&eacute;trica <code>ga:pageviews</code> y filtro <code>ga:previousPagePath</code> con la p&aacute;gina que queremos consultar</p>
<p>Los datos obtenidos nos dir&aacute;n si la navegaci&oacute;n que realiza el usuario es la que esperamos o por el contrario no lo es y por tanto el contenido no le interesa.</p>
<h3><strong>Conclusiones</strong>&nbsp;</h3>
Aunque esta herramienta es muy potente para el marketing web y s&oacute;lo hemos comentado algunas de las m&aacute;s importantes posibilidades que nos ofrece el API, tambi&eacute;n nos ofrece muchas m&aacute;s como seguimiento de campa&ntilde;as, comercio electr&oacute;nico, fidelizaci&oacute;n de clientes, etc.<br />
<p>Todo estos datos sobre el patr&oacute;n de comportamiento de los usuarios nos sirve para conseguir un mejor <a title="&iquest;C&oacute;mo hacemos el posicionamiento web?" href="/marketing-online/posicionamiento-web.html">posicionamiento web</a> y por tanto tener m&aacute;s posibilidades de &eacute;xito. Estas t&eacute;cnicas, mezcladas con los conocimientos de marketing tradicional, las utilizamos en Imaginanet para la consecuci&oacute;n de los objetivos planteados en los proyectos de <a title="Agencia de marketing online. &iquest;Qu&eacute; aportamos?" href="/marketing-online.html">marketing online</a> en que participamos.</p>
<p>En pr&oacute;ximas entradas, hablaremos de posibilidades m&aacute;s avanzadas que nos ofrece.</p>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px;"><!-- 		@page { margin: 2cm } 		P { margin-bottom: 0.21cm } 		A:link { so-language: zxx } -->
<p style="margin-bottom: 0cm;"><span style="font-family: Verdana,sans-serif;">Desde que Google sac&oacute; su herramienta Analytics nos proporcion&oacute; una nueva perspectiva para ver nuestra web desde los ojos de las personas que la visitan con un mont&oacute;n de estad&iacute;sticas de todo tipo. </span></p>
<p style="margin-bottom: 0cm;">&nbsp;</p>
<p style="margin-bottom: 0cm;"><span style="font-family: Verdana,sans-serif;">A primera vista desde el panel de control de Google Analytics, la gran cantidad de opciones y men&uacute;s que tenemos resulta hasta confusa para entender realmente que nos est&aacute;n diciendo y m&aacute;s a&uacute;n para gente inexperta. As&iacute; que tras un tiempo trabajando con ella, decid&iacute; ponerme manos a la obra para simplificar esta gran herramienta para hacerla un poco m&aacute;s sencilla.</span></p>
<p style="margin-bottom: 0cm;">&nbsp;</p>
<p style="margin-bottom: 0cm;"><span style="font-family: Verdana,sans-serif;">En primer lugar ech&eacute; un vistazo a la documentaci&oacute;n del API en la direcci&oacute;n <a href="http://code.google.com/intl/es-ES/apis/analytics/">http://code.google.com/intl/es-ES/apis/analytics/</a></span> <span style="font-family: Verdana,sans-serif;">y como era de esperar las posibilidades que nos ofrece esta complet&iacute;sima API son numerosas. A continuaci&oacute;n hablaremos de las conclusiones b&aacute;sicas que podemos obtener con ella, aunque en primer lugar deberemos conocer que estos datos est&aacute;n divididos en dos grupos, dimensiones que es lo que vamos a medir y las m&eacute;tricas, que es en qu&eacute; unidad lo vamos a medir.</span></p>
<p style="margin-bottom: 0cm;">&nbsp;</p>
<p style="margin-bottom: 0cm;"><span style="font-family: Verdana,sans-serif;">&iquest;Tiene buen contenido o dise&ntilde;o mi web?</span></p>
<p style="margin-bottom: 0cm;">&nbsp;</p>
<p style="margin-bottom: 0cm;"><span style="font-family: Verdana,sans-serif;">Tras interpretar los datos que obtenemos, podemos considerar si nuestra web tiene buenos contenidos o no desde dos puntos de vista, globalmente y espec&iacute;ficamente para una p&aacute;gina determinada.</span></p>
<p style="margin-bottom: 0cm;">&nbsp;</p>
<p style="margin-bottom: 0cm;"><span style="font-family: Verdana,sans-serif;">Desde el punto de vista global, deberemos prestar atenci&oacute;n al grupo de m&eacute;tricas M1. Visitor que nos dir&aacute; el tanto por cien de rebote de nuestra web. Este c&aacute;lculo lo haremos realizando la divisi&oacute;n de las m&eacute;tricas <code>ga:bounces</code> entre <code>ga:entrances</code> d&aacute;ndonos como resultado el n&uacute;mero de cuantas personas abandonan la web tras visitar nuestra p&aacute;gina inicial.</span></p>
<p style="margin-bottom: 0cm;">&nbsp;</p>
<p style="margin-bottom: 0cm;"><span style="font-family: Verdana,sans-serif;">Un alto n&uacute;mero en el tanto por cien de rebotes nos indica que la p&aacute;gina inicial no contiene o no muestra de manera correcta lo que el usuario esperaba encontrar en ella y por tanto se va a otra. </span></p>
<p style="margin-bottom: 0cm;">&nbsp;</p>
<p style="margin-bottom: 0cm;"><span style="font-family: Verdana,sans-serif;">Una vez determinado que el tanto por cien de rebote es lo m&aacute;s bajo posible, podemos estimar si estos contenidos globales son interesantes o no para el usuario mediante la m&eacute;trica </span><code>ga:timeOnSite</code> que nos proporciona la cantidad de tiempo que estuvo el usuario en nuestra web y la dimensi&oacute;n <span style="font-family: Verdana,sans-serif;"><code>ga:pageDepth</code>, que nos dice la cantidad media que los usuarios ven cuando entran en nuestra web.</span></p>
<p style="margin-bottom: 0cm;">&nbsp;</p>
<p style="margin-bottom: 0cm;">&nbsp;</p>
<p style="margin-bottom: 0cm;"><span style="font-family: Verdana,sans-serif;">Desde el punto de vista espec&iacute;fico para una determinada p&aacute;gina, si existe un alto n&uacute;mero n&uacute;mero de rebotes significa que al llegar a esa p&aacute;gina es confusa o no tiene inter&eacute;s para el usuario as&iacute; que deber&iacute;amos mejorar los aspectos donde falle.</span></p>
<p style="margin-bottom: 0cm;">&nbsp;</p>
<p style="margin-bottom: 0cm;"><span style="font-family: Verdana,sans-serif;">&iquest;Son buenas las palabras clave que utilizo para cada p&aacute;gina?</span></p>
<p style="margin-bottom: 0cm;">&nbsp;</p>
<p style="margin-bottom: 0cm;"><span style="font-family: Verdana,sans-serif;">Las palabras claves nos sirven junto al contenido de cada p&aacute;gina para describirla de cara a los buscadores. Para ver si las palabras claves que describen nuestras p&aacute;ginas son buenas podemos utilizar la m&eacute;trica <code>ga:entrances</code> junto a la dimensi&oacute;n <code>ga:landingPagePath</code> y as&iacute; indicarnos si hemos conseguido nuevas visitas desde buscadores a una p&aacute;gina concreta.</span></p>
<p style="margin-bottom: 0cm;">&nbsp;</p>
<p style="margin-bottom: 0cm;"><span style="font-family: Verdana,sans-serif;">&iquest;Cu&aacute;l es el comportamiento de los visitantes de mi web?</span></p>
<p style="margin-bottom: 0cm;">&nbsp;</p>
<p style="margin-bottom: 0cm;"><span style="font-family: Verdana,sans-serif;">Un valor interesante es el que nos proporciona la dimensi&oacute;n <code>ga:secondPagePath</code>, que nos dice cu&aacute;l fue la segunda p&aacute;gina que visit&oacute; el usuario tras ver nuestra web. &Eacute;sto nos indica que es lo que m&aacute;s llama la atenci&oacute;n en nuestra web pudiendo potenciar otras p&aacute;ginas que deber&iacute;an tener mejores resultados.</span></p>
<p style="margin-bottom: 0cm;">&nbsp;</p>
<p style="margin-bottom: 0cm;"><span style="font-family: Verdana,sans-serif;">Podemos observar tambi&eacute;n la navegaci&oacute;n que realizan los usuarios para p&aacute;ginas determinadas y ver desde qu&eacute; p&aacute;gina llegaron y a qu&eacute; p&aacute;gina fueron desde ella. Para ello tenemos que utilizar una gran caracter&iacute;stica de esta API que son los filtros, que nos permiten obtener una combinaci&oacute;n de dimensiones y m&eacute;tras filtrando los resultados para una dimensi&oacute;n o m&eacute;trica determinada.</span></p>
<p style="margin-bottom: 0cm;">&nbsp;</p>
<p style="margin-bottom: 0cm;"><span style="font-family: Verdana,sans-serif;">En este caso, para saber desde qu&eacute; p&aacute;gina llegaron a otra deberemos usar como par&aacute;metros</span></p>
<p style="margin-bottom: 0cm;"><span style="font-family: Verdana,sans-serif;">dimensi&oacute;n <code>ga:previousPagePath</code> m&eacute;trica <code>ga:pageviews</code> </span></p>
<p style="margin-bottom: 0cm;"><span style="font-family: Verdana,sans-serif;"><code>filtro <code>ga:nextPagePath</code> pagina_objetivo.html</code></span></p>
<p style="margin-bottom: 0cm;">&nbsp;</p>
<p style="margin-bottom: 0cm;"><span style="font-family: Verdana,sans-serif;">y para saber qu&eacute; p&aacute;gina visitaron desde la actual</span></p>
<p style="margin-bottom: 0cm;">&nbsp;</p>
<p style="margin-bottom: 0cm;"><span style="font-family: Verdana,sans-serif;"><code>dimensi&oacute;n <code>ga:nextPagePath</code><br />m&eacute;trica <code>ga:pageviews</code> </code></span></p>
<p style="margin-bottom: 0cm;"><span style="font-family: Verdana,sans-serif;"><code>filtro <code>ga:previousPagePath%3D~test.html</code></code></span></p>
<p style="margin-bottom: 0cm;">&nbsp;</p>
<p style="margin-bottom: 0cm;"><span style="font-family: Verdana,sans-serif;">Los datos obtenidos nos dir&aacute;n si la navegaci&oacute;n que realiza el usuario es la que esperamos o por el contrario no lo es y por tanto el contenido no le interesa.</span></p>
<p style="margin-bottom: 0cm;">&nbsp;</p>
<p style="margin-bottom: 0cm;">&nbsp;</p>
<p style="margin-bottom: 0cm;"><span style="font-family: Verdana,sans-serif;">Finalmente, debo decir que aunque esta herramienta es muy potente y que s&oacute;lo hemos comentado algunas de las m&aacute;s importantes posibilidades que nos ofrece el API y que podemos ver todo lo que podemos hacer aqu&iacute; </span></p>
<p style="margin-bottom: 0cm;"><span style="font-family: Verdana,sans-serif;">http://code.google.com/intl/es-ES/apis/analytics/docs/gdata/gdataReferenceDimensionsMetrics.html</span></p>
<p style="margin-bottom: 0cm;"><span style="font-family: Verdana,sans-serif;">, nos sirve para conseguir un mejor posicionamiento web y por tanto tener m&aacute;s posibilidades de &eacute;xito. Estas t&eacute;cnicas las utilizamos desde Imaginanet para conseguir que nuestros clientes tengan &eacute;xito <a href="http://www.imaginanet.com/posicionamiento-seo.html">http://www.imaginanet.com/posicionamiento-seo.html</a></span></p>
<p style="margin-bottom: 0cm;">&nbsp;</p>
<p style="margin-bottom: 0cm;"><span style="font-family: Verdana,sans-serif;">En pr&oacute;ximas entradas, hablaremos de posibilidades m&aacute;s avanzadas que nos ofrece.</span></p>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=19</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/usando-el-api-de-google-analytics-para-mejorar-nuestra-web.html</feedburner:origLink>
		</item>
				
		<item>
			<title>La vida más fácil con Google Mail (Gmail y Google Apps for your domain)</title>
			<link>http://www.imaginanet.com/blog/la-vida-mas-facil-con-google-mail-gmail-y-google-apps-for-your-domain.html</link>
			<guid>http://www.imaginanet.com/blog/la-vida-mas-facil-con-google-mail-gmail-y-google-apps-for-your-domain.html</guid>
			<comments>http://www.imaginanet.com/blog/la-vida-mas-facil-con-google-mail-gmail-y-google-apps-for-your-domain.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Wed, 16 Dec 2009 11:05:45 +0100</pubDate>
					<category><![CDATA[Google Apps]]></category>
					<description><![CDATA[Acabo de darme cuenta de que en GMail, aparece una novedad en color rojo que dice "&iexcl;Nuevo! Videos de Gmail" y veo que es una campa&ntilde;a que Google est&aacute; haciendo a sus usuarios ense&ntilde;&aacute;ndoles todo lo que pueden hacer con GMail. Podeis verla aqu&iacute;.En los v&iacute;deos se explican las distintas...]]></description>
			<content:encoded><![CDATA[>Acabo de darme cuenta de que en GMail, aparece una novedad en color rojo que dice "&iexcl;Nuevo! Videos de Gmail" y veo que es una campa&ntilde;a que Google est&aacute; haciendo a sus usuarios ense&ntilde;&aacute;ndoles todo lo que pueden hacer con GMail. <a title="Abrir en una ventana nueva" href="http://www.google.es/videosgmail" target="_blank">Podeis verla aqu&iacute;.</a><br /><br />En los v&iacute;deos se explican las distintas maravillas del cliente de correo electr&oacute;nico y del servidor. <br />Valorando todo lo que dicen, realmente es aplicable a Google Apps. Nosotros usamos Google Apps y estamos encantados, pero resulta que somos <a title="Ver servicios de integraci&oacute;n de Google Apps" href="/soluciones-on-line/google-apps.html">integradores de Google Apps</a>&nbsp; - para <a title="Ver soluciones de intranet en las que se puede integrar Google Apps" href="/soluciones-on-line/intranet-extranet/intranet.html">intranets</a>, <a title="Ver soluciones de extranet en las que se puede integrar Google Apps" href="/soluciones-on-line/intranet-extranet/extranet.html">extranets</a>, gestores de contenido, y hasta en <a title="Ver servicios de dise&ntilde;o y programaci&oacute;n de p&aacute;ginas web" href="/diseno-web.html">las p&aacute;ginas web que dise&ntilde;amos y desarrollamos</a> -&nbsp; y los clientes que tambi&eacute;n utilizan Google Apps for your Domain, tambi&eacute;n est&aacute;n muy contentos.<br />Razones que tenemos para ello son las explicadas en esta p&aacute;gina que ha creado Google, pero adem&aacute;s incluimos una serie de ventajas adicionales:<br />- Google Mail. Al poder configurarlo como servidor IMAP, es fant&aacute;stico, te permite sincronizar el correo desde cualquier dispositivo. Cuando leo un email en mi tel&eacute;fono m&oacute;vil, me lo marca como le&iacute;do en el resto de clientes de correo, si env&iacute;o un email, lo veo en la bandeja de enviados de todos mis clientes de correo. Es algo muy c&oacute;modo.<br />- Google Calendar. Permite tener calendarios de empresa para distintas tareas, por ejemplo, podemos tener el calendario de trabajos de dise&ntilde;o web, el cual est&aacute; compartido con dise&ntilde;adores y maquetadores, el calendario de entrega de proyectos que est&aacute; compartido con las personas encargadas de hacer seguimiento de proyectos, ... Adem&aacute;s, con cada cliente compartimos un calendario con los diferentes hitos del proyecto, conforme el proyecto va avanzando, el calendario se actualiza inmediatamente. Y todo sincronizado con el tel&eacute;fono m&oacute;vil, portatil, ...<br />- Google Docs. Qu&eacute; podemos decir de una herramienta ofim&aacute;tica que permite compartir con clientes y compa&ntilde;eros de trabajo hojas de c&aacute;lculo con presupuestos, documentos de texto con el seguimiento o la funcionalidad de un proyecto, etc.<br />- Google Talk. Una herramienta imprescindible en una intranet, permite mantener conversaciones privadas entre usuario y entre distintas sucursales de la empresa, con la gran ventaja de que todo el texto que hemos escrito nos lo env&iacute;a por email a nuestra cuenta de correo y de nuestro compa&ntilde;ero de charlas.<br /><br />...<br /><br />Y lo que cuentan en los v&iacute;deos colgados explican los siguientes temas:<br />- Cadenas de conversaci&oacute;n de Gmail. Aqu&iacute; vemos c&oacute;mo al iniciar un mensaje, las respuestas que este tiene se guardan todas agrupadas de forma que la conversaci&oacute;n est&eacute; toda en el mismo mensaje. Esta utilidad est&aacute; muy bien, aunque a veces genera peque&ntilde;as confusiones, es muy &uacute;til os lo aseguro.<br /> 
<object width="425" height="344" data="http://www.youtube.com/v/2LoeyPlAnvo&amp;color1=0xb1b1b1&amp;color2=0xcfcfcf&amp;hl=en_US&amp;feature=player_embedded&amp;fs=1" type="application/x-shockwave-flash">
<param name="data" value="http://www.youtube.com/v/2LoeyPlAnvo&amp;color1=0xb1b1b1&amp;color2=0xcfcfcf&amp;hl=en_US&amp;feature=player_embedded&amp;fs=1" />
<param name="allowFullScreen" value="true" />
<param name="allowScriptAccess" value="always" />
<param name="src" value="http://www.youtube.com/v/2LoeyPlAnvo&amp;color1=0xb1b1b1&amp;color2=0xcfcfcf&amp;hl=en_US&amp;feature=player_embedded&amp;fs=1" />
<param name="allowfullscreen" value="true" />
</object>
<br /><br />- &iquest;No hay conexi&oacute;n a internet? Sin problemas, usando Google Gears podemos trabajar con nuestro Google Mail y cuando tengamos conexi&oacute;n a internet, autom&aacute;ticamente lo detectar&aacute; y recibir&aacute; los mensajes pendientes de recibir, as&iacute; como enviar&aacute; aquellos que est&eacute;n pendientes de env&iacute;o.<br /> 
<object width="425" height="344" data="http://www.youtube.com/v/ymXEr9Zs37w&amp;color1=0xb1b1b1&amp;color2=0xcfcfcf&amp;hl=en_US&amp;feature=player_embedded&amp;fs=1" type="application/x-shockwave-flash">
<param name="data" value="http://www.youtube.com/v/ymXEr9Zs37w&amp;color1=0xb1b1b1&amp;color2=0xcfcfcf&amp;hl=en_US&amp;feature=player_embedded&amp;fs=1" />
<param name="allowFullScreen" value="true" />
<param name="allowScriptAccess" value="always" />
<param name="src" value="http://www.youtube.com/v/ymXEr9Zs37w&amp;color1=0xb1b1b1&amp;color2=0xcfcfcf&amp;hl=en_US&amp;feature=player_embedded&amp;fs=1" />
<param name="allowfullscreen" value="true" />
</object>
<br /><br />- AntiSpam. Una aplicaci&oacute;n anti-spam que funciona muy fina.<br /> 
<object width="425" height="344" data="http://www.youtube.com/v/q_CzSr3QL5Y&amp;color1=0xb1b1b1&amp;color2=0xcfcfcf&amp;hl=en_US&amp;feature=player_embedded&amp;fs=1" type="application/x-shockwave-flash">
<param name="data" value="http://www.youtube.com/v/q_CzSr3QL5Y&amp;color1=0xb1b1b1&amp;color2=0xcfcfcf&amp;hl=en_US&amp;feature=player_embedded&amp;fs=1" />
<param name="allowFullScreen" value="true" />
<param name="allowScriptAccess" value="always" />
<param name="src" value="http://www.youtube.com/v/q_CzSr3QL5Y&amp;color1=0xb1b1b1&amp;color2=0xcfcfcf&amp;hl=en_US&amp;feature=player_embedded&amp;fs=1" />
<param name="allowfullscreen" value="true" />
</object>
<br /><br />- Chat de video y voz.<br />
<object width="425" height="344" data="http://www.youtube.com/v/Ijy3HMDygzo&amp;color1=0xb1b1b1&amp;color2=0xcfcfcf&amp;hl=en_US&amp;feature=player_embedded&amp;fs=1" type="application/x-shockwave-flash">
<param name="allowFullScreen" value="true" />
<param name="allowScriptAccess" value="always" />
<param name="src" value="http://www.youtube.com/v/Ijy3HMDygzo&amp;color1=0xb1b1b1&amp;color2=0xcfcfcf&amp;hl=en_US&amp;feature=player_embedded&amp;fs=1" />
<param name="allowfullscreen" value="true" />
</object>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=18</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/la-vida-mas-facil-con-google-mail-gmail-y-google-apps-for-your-domain.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Texto a voz usando el elemento Audio de HTML5</title>
			<link>http://www.imaginanet.com/blog/texto-a-voz-usando-el-elemento-audio-de-html5.html</link>
			<guid>http://www.imaginanet.com/blog/texto-a-voz-usando-el-elemento-audio-de-html5.html</guid>
			<comments>http://www.imaginanet.com/blog/texto-a-voz-usando-el-elemento-audio-de-html5.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Tue, 15 Dec 2009 11:18:24 +0100</pubDate>
					<category><![CDATA[HTML5]]></category>
					<category><![CDATA[Accesibilidad]]></category>
					<description><![CDATA[Weston Ruter ha creado un mashup que enlaza el soporte de Audio en HTML5 en navegadores modernos (no more Internet Explorer please) con la nueva API de traducción de Google.Hace poco que Google Translate anunció la posibilidad de escuchar traducciones habladas en inglés via texto a voz (TTS - Text To Speech). Buscando en el...]]></description>
			<content:encoded><![CDATA[>Weston Ruter ha creado un mashup que <a title="Abrir en una ventana nueva" href="http://weston.ruter.net/projects/google-tts/" target="_blank">enlaza el soporte de Audio en HTML5</a> en navegadores modernos (no more Internet Explorer please) con la nueva <a title="Abrir en una ventana nueva" href="http://googleblog.blogspot.com/2009/11/new-look-for-google-translate.html" target="_blank">API de traducción de Google</a>.<br /><br />Hace poco que Google Translate anunció la posibilidad de escuchar traducciones habladas en inglés via texto a voz (TTS - Text To Speech). Buscando en el panel de red de Firebug de donde estaban llegando los datos TTS, se ve que el audio está en formato MP3 y se ejecuta con una consulta HTTP GET: http://translate.google.com/translate_tts?tl=en&q=text.<br /><br />Google Translate, advierte de que el servicio sólo está disponible para pequeñas traducciones a inglés, y el servicio web de texto a voz se limita a una cantidad de texto no superior a 100 caracteres.<br /><br />Otra restricción es que el servicio devuelve un error 404 si la petición incluye un Referer en el header (parece ser que el referer debe ser translate.google.com).<br /><br />Según dice Weston Ruter, creó este mashup viendo las limitaciones del web service TTS que sólo puede usarlo Google Translate, para utilizarlo desde cualquier navegador que admita el elemento Audio de HTML5. El mashup web utiliza este último y un atributo rel="noreferrer".<br /><br />Hay otros experimentos de texto a voz, <a title="Abrir en una ventana nueva" href="http://www.clochix.net/post/2009/03/14/Et-en-plus-il-parle" target="_blank">por ejemplo esta página</a>. Ójala que Google haga pública su API de traducción.<br />]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=17</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/texto-a-voz-usando-el-elemento-audio-de-html5.html</feedburner:origLink>
		</item>
				
		<item>
			<title>jQuery ColorPicker. Tres plugins que merece la pena tener en cuenta.</title>
			<link>http://www.imaginanet.com/blog/jquery-colorpicker-tres-plugins-de-jquery-que-merece-la-pena-tener-en-cuenta.html</link>
			<guid>http://www.imaginanet.com/blog/jquery-colorpicker-tres-plugins-de-jquery-que-merece-la-pena-tener-en-cuenta.html</guid>
			<comments>http://www.imaginanet.com/blog/jquery-colorpicker-tres-plugins-de-jquery-que-merece-la-pena-tener-en-cuenta.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Tue, 15 Dec 2009 10:47:35 +0100</pubDate>
					<category><![CDATA[Web 2.0]]></category>
					<category><![CDATA[JavaScript]]></category>
					<category><![CDATA[jQuery]]></category>
					<description><![CDATA[Todos alguna vez, hemos necesitado inclu&iacute;r campos de selecci&oacute;n de color (colorpicker) cuando realizamos zonas de administraci&oacute;n o backOffice.Est&aacute; muy pasado de moda y queda demasiado rudimentario incluir campos de texto donde se introduzca el c&oacute;digo hexadecimal del color deseado, adem&aacute;s,...]]></description>
			<content:encoded><![CDATA[>Todos alguna vez, hemos necesitado inclu&iacute;r campos de selecci&oacute;n de color (colorpicker) cuando realizamos zonas de administraci&oacute;n o backOffice.<br />Est&aacute; muy pasado de moda y queda demasiado rudimentario incluir campos de texto donde se introduzca el c&oacute;digo hexadecimal del color deseado, adem&aacute;s, de esta forma es un poco complicado explicar lo qu&eacute; significa el c&oacute;digo #ff0000. Si queremos hacer las cosas f&aacute;ciles de usar, y proporcionar al usuario algo f&aacute;cil e intuitivo, hay que incluir una aplicaci&oacute;n de selecci&oacute;n de color desde donde el usuario seleccione el color deseado de forma visual.<br /><br />En este art&iacute;culo mencionamos tres plugins de jQuery para la inclusi&oacute;n de un colorPicker en campos de formularios.<br /><br /><a title="Abrir en una ventana nueva" href="http://acko.net/dev/farbtastic" target="_blank">Farbtastic</a> est&aacute; escrito por Steven Writtens con licencia GPL. Si quieres m&aacute;s informaci&oacute;n sobre el plugin, <a title="Abrir en una ventana nueva" href="http://acko.net/dev/farbtastic" target="_blank">pulsa aqu&iacute;</a>. Es muy f&aacute;cil de incluir:<br />1. Incluir los archivos javaScript y CSS en el HTML de tu p&aacute;gina web.<br />
<pre class="code xml">
  <script src="/imaginanet/farbtastic.js" type="text/javascript"></script>
  <link rel="stylesheet" href="farbtastic.css" type="text/css" />
</pre>
<br />2. A&ntilde;adir un elemento que sea el contenedor del gr&aacute;fico y el campo de texto, y asignarles un identificador a cada uno de ellos.<br />
<pre class="code xml"><form>
  <input id="color" name="color" type="text" value="#123456" />
</form>
<div id="colorpicker"></div>
</pre>
3. A&ntilde;adir al evento ready() un controlador que inicializa el color picker y lo enlaza con el campo de texto.<br />
<pre class="code xml">
&lt;script type="text/javascript"&gt;
  $(document).ready(function() {
    $('#colorpicker').farbtastic('#color');
  });
&lt;/script&gt;
</pre>
<a title="Abrir en una ventana nueva" href="http://www.eyecon.ro/colorpicker/" target="_blank">ColorPicker</a>, est&aacute; programado por Stefan Petre. Con dos tipos de licencia, MIT y GPL. Puedes ver su p&aacute;gina web <a title="Abrir en una ventana nueva" href="http://www.eyecon.ro/colorpicker/" target="_blank">pulsando aqu&iacute;</a>.<br />Si quieres ver la gu&iacute;a r&aacute;pida de implementaci&oacute;n, pulsa aqu&iacute;. La inclusi&oacute;n en tu p&aacute;gina web es muy r&aacute;pida, cargas los archivos javaScript y CSS necesarios, creas un campo de texto que sea el que incluya el colorPicker y le asignas un identificador, a continuaci&oacute;n, en el evento ready(), lo inicializamos asign&aacute;ndoselo al identificador del campo creado.<br />
<pre class="code js">$('idCampoDeTexto').ColorPicker();
</pre>
Si queremos activarlo con opciones personalizadas:<br />
<pre class="code js">$('idCampoDeTexto').ColorPicker({option1:val1,opt2:val2,...});
</pre>
<br /><a title="Abrir en una ventana nueva" href="http://www.digitalmagicpro.com/jPicker/" target="_blank">jPicker</a> es una migraci&oacute;n del <a title="Abrir en una ventana nueva" href="http://johndyer.name/post/2007/09/PhotoShop-like-JavaScript-Color-Picker.aspx" target="_blank">plugin escrito para Prototype por John Dyers</a> (fant&aacute;stico plugin). Puedes ver m&aacute;s informaci&oacute;n sobre el plugin en la <a title="Abrir en una ventana nueva" href="http://www.digitalmagicpro.com/jPicker/" target="_blank">p&aacute;gina de jPicker</a>.<br /><br /><br />]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=16</wfw:commentRss>
			<slash:comments>2</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/jquery-colorpicker-tres-plugins-de-jquery-que-merece-la-pena-tener-en-cuenta.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Rendimiento de las URIs con datos</title>
			<link>http://www.imaginanet.com/blog/rendimiento-de-las-uris-con-datos.html</link>
			<guid>http://www.imaginanet.com/blog/rendimiento-de-las-uris-con-datos.html</guid>
			<comments>http://www.imaginanet.com/blog/rendimiento-de-las-uris-con-datos.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Mon, 14 Dec 2009 11:55:47 +0100</pubDate>
					<category><![CDATA[JavaScript]]></category>
					<category><![CDATA[CSS]]></category>
					<category><![CDATA[Navegadores]]></category>
					<description><![CDATA[En el blog de Ravelrumba, han hecho un peque&ntilde;o experimento con URIs de datos y su rendimiento en la carga de una p&aacute;gina web. En el estudio s&oacute;lo se ha utilizado Firefox 3.5 con la cach&eacute; vac&iacute;a.Los resultados no son interesantes por las respuestas que nos proporcionan, sino por las preguntas que...]]></description>
			<content:encoded><![CDATA[>En el <a title="Abrir en una ventana nueva" href="http://www.ravelrumba.com/blog/data-uris-for-css-images-more-tests-more-questions/" target="_blank">blog de Ravelrumba</a>, han hecho un peque&ntilde;o experimento con URIs de datos y su rendimiento en la carga de una p&aacute;gina web. En el estudio s&oacute;lo se ha utilizado Firefox 3.5 con la cach&eacute; vac&iacute;a.<br /><br />Los resultados no son interesantes por las respuestas que nos proporcionan, sino por las preguntas que hacen aparecer al respecto.<br /><br />En el experimento se han usado 31 im&aacute;genes y se han convertido a data URIs con <a title="Abrir en una ventana nueva" href="http://github.com/nzakas/cssembed" target="_blank">CSSEmbed</a>. En un caso adicional, se ha usado <a title="Abrir en una ventana nueva" href="http://duris.ru/" target="_blank">DURIS</a> para separar todas las URIs de datos en un archivo CSS aparte, as&iacute;, la etiqueta &lt;head&gt; se queda mucho m&aacute;s peque&ntilde;a y as&iacute;, carga m&aacute;s r&aacute;pido.<br /><br />Los tres escenarios planteados, llevan a un rendimiento muy parecido (usando HTTPWatch, los tiempos de carga son 1,35 s, 1,13 s y 1,13 s), viendo que los escenarios con data URI son un poco mejores. Es m&aacute;s interesante ver que un usuario que deja un comentario desde Sur&aacute;frica proporciona unos resultados bastante distintos: 4,04 s, 1,44 s, 1,92 s. En este caso, el retardo que existe para cargar 31 im&aacute;genes, puede conllevar estos tiempos de carga.<br /><br />Otro factor importante es la velocidad que percibe el usuario, al fin y al cabo, lo que m&aacute;s tiene que ver con el rendimiento. Los dos escenarios funcionan con la misma velocidad percibida, el segundo de ellos parece ser mejor ya que las im&aacute;genes se cargan en una hoja de estilos al final de la p&aacute;gina, despu&eacute;s de haberse cargado un script.<br /><br />El estudio saca a la luz preguntas sobre la carga de URIs con datos. Otro usuario del web, comenta que ha enviado un gr&aacute;fico que muestra como las URIs a im&aacute;genes tardan m&aacute;s en cargar que las im&aacute;genes descargadas de una forma convencional. Este es el tipo de cosas que ser&iacute;a bueno investigar.<br /><br />En el mismo blog se puede ver un estudio sobre el <a title="Abrir en una ventana nueva" href="http://www.ravelrumba.com/blog/a-look-at-how-browsers-download-and-render-css-background-images/" target="_blank">rendimiento de las im&aacute;genes de fondo</a> en distintos navegadores.]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=14</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/rendimiento-de-las-uris-con-datos.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Google: más búsquedas en tiempo real.</title>
			<link>http://www.imaginanet.com/blog/google-mas-busquedas-en-tiempo-real.html</link>
			<guid>http://www.imaginanet.com/blog/google-mas-busquedas-en-tiempo-real.html</guid>
			<comments>http://www.imaginanet.com/blog/google-mas-busquedas-en-tiempo-real.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Mon, 14 Dec 2009 11:22:11 +0100</pubDate>
					<category><![CDATA[Google]]></category>
					<category><![CDATA[Buscadores]]></category>
					<category><![CDATA[Web 2.0]]></category>
					<description><![CDATA[En abril de este año, Google empezó a mostrar resultados de búsquedas en Twitter en tiempo real y así ver lo que dice la gente en el mismo momento.Ahora, los usuarios podrán ver que en la parte superior de una búsqueda de resultados y siempre que tenga sentido para la búsqueda, actualizaciones en direto de los contenidos...]]></description>
			<content:encoded><![CDATA[>En abril de este año, Google empezó a mostrar resultados de búsquedas en Twitter en tiempo real y así ver lo que dice la gente en el mismo momento.<br />Ahora, los usuarios podrán ver que en la parte superior de una búsqueda de resultados y siempre que tenga sentido para la búsqueda, actualizaciones en direto de los contenidos que la gente escribe en Twitter, FriendFeed, Facebook, MySpace, FriendFeed, Jaiku e Identi.ca.<br /><br />Además, incluirá los artículos que se hayan rastreado para este tema en los medios que rastrea <a title="Abrir en una ventana nueva" href="http://news.google.com/" target="_blank">Google News</a> o el <a title="Abrir en una ventana nueva" href="http://blogsearch.google.com/" target="_blank">buscador de blogs de Google</a>.<br /><br />En <a title="Abrir en una ventana nueva" href="http://www.google.com/trends" target="_blank">Google Trends</a> se ha incluído también esta opción para ver estadísticas de las palabras que más se consultan en el buscador en tiempo real.<br /><br />En el video siguiente se ve como una búsqueda se va llenando de comentarios de Twitter que van dejando los usuarios sobre el tema:<br /><br /> 
<object width="425" height="344" data="http://www.youtube.com/v/WRkYmx4A9Do&color1=0xb1b1b1&color2=0xcfcfcf&hl=en_US&feature=player_embedded&fs=1" type="application/x-shockwave-flash">
<param name="data" value="http://www.youtube.com/v/WRkYmx4A9Do&color1=0xb1b1b1&color2=0xcfcfcf&hl=en_US&feature=player_embedded&fs=1" />
<param name="allowFullScreen" value="true" />
<param name="allowScriptAccess" value="always" />
<param name="src" value="http://www.youtube.com/v/WRkYmx4A9Do&color1=0xb1b1b1&color2=0xcfcfcf&hl=en_US&feature=player_embedded&fs=1" />
<param name="allowfullscreen" value="true" />
</object>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=12</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/google-mas-busquedas-en-tiempo-real.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Google Goggles. Usa imágenes para buscar en la web.</title>
			<link>http://www.imaginanet.com/blog/google-goggles--usa-imagenes-para-buscar-en-la-web-.html</link>
			<guid>http://www.imaginanet.com/blog/google-goggles--usa-imagenes-para-buscar-en-la-web-.html</guid>
			<comments>http://www.imaginanet.com/blog/google-goggles--usa-imagenes-para-buscar-en-la-web-.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Sat, 12 Dec 2009 17:29:13 +0100</pubDate>
					<category><![CDATA[Google]]></category>
					<category><![CDATA[Buscadores]]></category>
					<description><![CDATA[Como una imagen vale más que mil palabras, en Google acaban de lanzar un servicio de búsqueda a partir de una foto. Sácale una foto y te devolverá resultados relacionados con el tema.Sólo funciona en dispositivos con Android y reconoce lugares, obras de arte, logotipos… incluso, si estás en un lugar destacado, sólo has de...]]></description>
			<content:encoded><![CDATA[>Como una imagen vale más que mil palabras, en Google acaban de lanzar un <a title="Abrir en ventana nueva. Google goggles." href="http://www.google.com/mobile/goggles/" target="_blank">servicio de búsqueda a partir de una foto</a>. Sácale una foto y te devolverá resultados relacionados con el tema.<br />Sólo funciona en dispositivos con Android y reconoce lugares, obras de arte, logotipos… incluso, si estás en un lugar destacado, sólo has de activar el GPS, mandar la localización y se te devolverá la información sobre el lugar donde te encuentres..<br /><br />    
<object width="560" height="340" data="http://www.youtube.com/v/Hhgfz0zPmH4&hl=es_ES&fs=1&rel=0" type="application/x-shockwave-flash">
<param name="data" value="http://www.youtube.com/v/Hhgfz0zPmH4&hl=es_ES&fs=1&rel=0" />
<param name="allowFullScreen" value="true" />
<param name="allowscriptaccess" value="always" />
<param name="src" value="http://www.youtube.com/v/Hhgfz0zPmH4&hl=es_ES&fs=1&rel=0" />
<param name="allowfullscreen" value="true" />
</object>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=11</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/google-goggles--usa-imagenes-para-buscar-en-la-web-.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Búsquedas personalizadas para todos los usuarios.</title>
			<link>http://www.imaginanet.com/blog/busquedas-personalizadas-para-todos-los-usuarios-.html</link>
			<guid>http://www.imaginanet.com/blog/busquedas-personalizadas-para-todos-los-usuarios-.html</guid>
			<comments>http://www.imaginanet.com/blog/busquedas-personalizadas-para-todos-los-usuarios-.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Mon, 14 Dec 2009 11:34:54 +0100</pubDate>
					<category><![CDATA[Google]]></category>
					<category><![CDATA[SEO]]></category>
					<category><![CDATA[Web 2.0]]></category>
					<description><![CDATA[Hace unos a&ntilde;os, nac&iacute;an las b&uacute;squedas personalizadas de Google, en donde se comenzaba a modificar los resultados en funci&oacute;n de los intereses del usuario. Un a&ntilde;o m&aacute;s tarde, se comenzaba a almacenar y a mostrar el historial de b&uacute;squedas de cada usuario que se hab&iacute;a registrado...]]></description>
			<content:encoded><![CDATA[><p>Hace unos a&ntilde;os, nac&iacute;an las b&uacute;squedas personalizadas de Google, en donde se comenzaba a modificar los resultados en funci&oacute;n de los intereses del usuario. Un a&ntilde;o m&aacute;s tarde, se comenzaba a almacenar y a mostrar el historial de b&uacute;squedas de cada usuario que se hab&iacute;a registrado previamente con una cuenta de usuario de Google.</p>
<p>El buscador ven&iacute;a almacenando, por cuestiones t&eacute;cnicas, las b&uacute;squedas que se realizan desde cada una de las direcciones IP que se conectan al servicio. Sin embargo, la compa&ntilde;&iacute;a ha anunciado oficialmente que el historial de b&uacute;squedas se va a almacenar durante 6 meses para todos los usuarios, y no se relacionar&aacute; con nuestra direcci&oacute;n IP, sino con una 'cookie' de nuestro navegador web, incluso cuando el usuario no dispone de cuenta en Google.</p>
<p>Con esta 'cookie' (que se puede borrar en cualquier momento), Google va a distinguirnos no ya por nuestra direcci&oacute;n IP, sino por el navegador web que utilicemos. De esta manera, aunque nuestro proveedor de Internet nos cambie la direcci&oacute;n IP, o aunque estemos con nuestro port&aacute;til en otro pa&iacute;s, Google va a saber durante 180 d&iacute;as las b&uacute;squedas que hemos realizado.</p>
<p>El objetivo es, seg&uacute;n <a title="Abrir en una ventana nueva" href="http://googleblog.blogspot.com/2009/12/personalized-search-for-everyone.html" target="_blank">este post oficial</a> personalizar nuestras b&uacute;squedas, y ofrecernos los resultados m&aacute;s adecuados a nuestros gustos y preferencias. As&iacute;, por ejemplo, si cuando buscamos 'barcelona' siempre acabamos haciendo click en las p&aacute;ginas de hoteles, la siguiente vez que lo consultemos quiz&aacute; veamos sitios web de hoteles en las primeras posiciones.</p>
<p>Esta nueva caracter&iacute;stica del buscador nos trae consigo de nuevo la duda acerca de si Google va a tener en cuenta estos clicks para modificar los resultados tambi&eacute;n del resto de usuarios y cambiar el posicionamiento general de las b&uacute;squedas. Pero tambi&eacute;n traer&aacute; consigo una importante pol&eacute;mica sobre la privacidad de todos nosotros, puesto que desde ahora, en caso de que queramos cuidar un poco m&aacute;s los datos expuestos ante Google, habr&aacute; que preocuparse de eliminar la 'cookie' de 'google.com' (o el dominio de la versi&oacute;n local que utilicemos).</p>
<p>Para borrar esta 'cookie' existen varias soluciones, para Firefox, est&aacute;n las extensiones '<a title="Abrir en una ventana nueva" href="https://addons.mozilla.org/en-US/firefox/addon/10354" target="_blank">Google-anon</a>' o '<a title="Abrir en una ventana nueva" href="https://addons.mozilla.org/en-US/firefox/addon/1243" target="_blank">Cookie Manager</a>', <a title="Abrir en una ventana nueva" href="http://support.microsoft.com/kb/278835" target="_blank">este link</a> sobre las cookies en MS IExplorer, o <a title="Abrir en una ventana nueva" href="http://www.aboutcookies.org/Default.aspx?page=2" target="_blank">esta p&aacute;gina</a> m&aacute;s gen&eacute;rica sobre 'cookies'.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=13</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/busquedas-personalizadas-para-todos-los-usuarios-.html</feedburner:origLink>
		</item>
				
		<item>
			<title>HighCharts. Un API de gráficos bastante buena.</title>
			<link>http://www.imaginanet.com/blog/highcharts-un-api-de-graficos-bastante-buena.html</link>
			<guid>http://www.imaginanet.com/blog/highcharts-un-api-de-graficos-bastante-buena.html</guid>
			<comments>http://www.imaginanet.com/blog/highcharts-un-api-de-graficos-bastante-buena.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Mon, 14 Dec 2009 15:46:27 +0100</pubDate>
					<category><![CDATA[JavaScript]]></category>
					<category><![CDATA[jQuery]]></category>
					<description><![CDATA[Todos queremos mejores librer&iacute;as javascript de gr&aacute;ficos. Dojo tiene una buena opci&oacute;n que es Protovis, y por ah&iacute; hay muchas librer&iacute;as (deja un comentario con tu favorita).La &uacute;ltima en aparecer es HighCharts que usa tanto jQuery como MooTools para las tareas JavaScript m&aacute;s frecuentes....]]></description>
			<content:encoded><![CDATA[>Todos queremos mejores librer&iacute;as javascript de gr&aacute;ficos. Dojo tiene una buena opci&oacute;n que es <a title="Abrir en una ventana nueva" href="http://vis.stanford.edu/protovis/" target="_blank">Protovis</a>, y por ah&iacute; hay muchas librer&iacute;as (deja un comentario con tu favorita).<br />La &uacute;ltima en aparecer es <a title="Abrir en una ventana nueva" href="http://highcharts.com/" target="_blank">HighCharts</a> que usa tanto jQuery como MooTools para las tareas JavaScript m&aacute;s frecuentes. Adem&aacute;s, Internet Explorer necesita ExCanvas que emula al elemento Canvas.<br />Un ejemplo de gr&aacute;fica:<br />
<pre class="code js">var chart1 = new Highcharts.Chart({
         chart: {
            renderTo: 'chart-container-1',
            defaultSeriesType: 'bar'
         },
         title: {
            text: 'Fruit Consumption'
         },
         xAxis: {
            categories: ['Apples', 'Bananas', 'Oranges]
         },
         yAxis: {
            title: {
               text: 'Fruit eaten'
            }
         },
         series: [{
            name: 'Jane',
            data: [1, 0, 4]
         }, {
            name: 'John',
            data: [5, 7, 3]
         }]
      });
</pre>
<br />Devuelve algo as&iacute;:<br /><br /><img title="HighCharts ejemplo" src="/blog_files/images/highcharts.png" alt="HighCharts ejemplo" />]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=15</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/highcharts-un-api-de-graficos-bastante-buena.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Google Analytics desbloquea la carga de webs lanzando el modo asíncrono (Async Mode)</title>
			<link>http://www.imaginanet.com/blog/google-analytics-desbloquea-la-carga-de-webs-lanzando-el-modo-asincrono-async-mode.html</link>
			<guid>http://www.imaginanet.com/blog/google-analytics-desbloquea-la-carga-de-webs-lanzando-el-modo-asincrono-async-mode.html</guid>
			<comments>http://www.imaginanet.com/blog/google-analytics-desbloquea-la-carga-de-webs-lanzando-el-modo-asincrono-async-mode.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Wed,  2 Dec 2009 16:10:25 +0100</pubDate>
					<category><![CDATA[JavaScript]]></category>
					<category><![CDATA[Google Analytics]]></category>
					<description><![CDATA[Gran noticia la que acabo de leer que Google Analytics lanza un modo de seguimiento as&iacute;ncrono "Google analytics launches Asynchronous Tracking" (click aqu&iacute; para ver art&iacute;culo original).Al fin nuestro navegador no se va a enganchar cargando el c&oacute;digo JavaScript.El sistema har&aacute; que las webs...]]></description>
			<content:encoded><![CDATA[>Gran noticia la que acabo de leer que Google Analytics lanza un modo de seguimiento as&iacute;ncrono "<em>Google analytics launches Asynchronous Tracking</em>" (<a title="Abrir en una ventana nueva" href="http://googlecode.blogspot.com/2009/12/google-analytics-launches-asynchronous.html" target="_blank">click aqu&iacute; para ver art&iacute;culo original</a>).<br /><br />Al fin nuestro navegador no se va a enganchar cargando el c&oacute;digo JavaScript.<br /><br /><strong>El sistema har&aacute; que las webs funcionen m&aacute;s r&aacute;pido:</strong><br />El mayor problema de cargar archivos JavaScript es que bloquea el renderizado de la p&aacute;gina web y la descarga de otros recursos. En el nuevo modelo as&iacute;ncrono de Google Analytics, se utiliza el elemento Script del DOM.<br />Google Analytics, con su archivo ga.js, es un ejemplo perfecto de un script que debiera cargarse de forma as&iacute;ncrona, ya que no a&ntilde;ade contenido alguno a la p&aacute;gina, con lo cual, ser&iacute;a ideal cargarlo sin bloquear las im&aacute;genes y hojas de estilo que har&aacute;n que los usuarios vean lo que realmente han venido a ver: nuestra p&aacute;gina web.<br /><strong><br />Se ha mejorado la estabilidad:</strong><br />&iquest;Qu&eacute; pasa si un script tarda mucho tiempo en cargarse, o falla su carga? El usuario se encuentra ante una p&aacute;gina en blanco, ya que los scripts bloquean el renderizado de la web. Aunque Google Analytics tiene una infraestructura muy grande tras &eacute;l, cualquier recurso, sobre todo de terceros, tiene que a&ntilde;adirse con cautela. Es una gran noticia que GA est&aacute; proporcionando patrones que permite el renderizado de las webs mientras se carga ga.js.&nbsp;<br /><br /><strong>&iquest;Qu&eacute; hay que hacer para incluir ga.js en modo as&iacute;ncrono?</strong> cambia tu script para que sea de la forma siguiente:
<pre class="code js">var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXX-X']);
_gaq.push(['_trackPageview']);
(function() {
   var ga = document.createElement('script');
   ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
   ga.setAttribute('async', 'true');
   document.documentElement.firstChild.appendChild(ga);
})();
</pre>
<br /> 
<ul>
<li>L&oacute;gicamente, tienes que sustituir "UA-XXXXX-X" por tu ID.</li>
<li>Al cargarse ga.js de forma as&iacute;ncrona, tiene que existir una forma para que algunas funciones de GA se puedan utilizar cuando el c&oacute;digo se termina de cargar. Esto se hace introduciendo comandos en la cola del objeto de Google Analytics, _gaq.</li>
<li>Una vez que todos los comandos callback se han puesto en cola, se carga el script ga.js. Esto se empaqueta en una funci&oacute;n as&iacute;ncrona para as&iacute; evitar conflictos de namespace.</li>
<li>Se crea un elemento "script" y su fuente "src" se pone al valor correcto de la URL de ga.js. Mirando m&aacute;s alla, en el soporte que se incluye en HTML5 a los scripts as&iacute;ncronos, el atributo "async" se pone a "true", muy bueno! La ventaja m&aacute;s importante es que le dice al navegador que los siguientes scripts se pueden ejecutar de forma inmediata (no tienen que esperar a que se carge ga.js). La &uacute;ltima l&iacute;nea a&ntilde;ade el elemento script al DOM. Esto es lo que ejecuta la descarga de ga.js. En muchos c&oacute;digos se hace document.getElementsByTagName(&rdquo;head&rdquo;)[0].appendChild, pero esto falla si el documento no tiene elemento head. Esta forma de hacerlo, es m&aacute;s robusta.</li>
</ul>
<br />
<p>&nbsp;</p>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=9</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/google-analytics-desbloquea-la-carga-de-webs-lanzando-el-modo-asincrono-async-mode.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Galería de fotos polaroid, sólo usando CSS 3</title>
			<link>http://www.imaginanet.com/blog/galeria-de-fotos-polaroid-solo-usando-css-3.html</link>
			<guid>http://www.imaginanet.com/blog/galeria-de-fotos-polaroid-solo-usando-css-3.html</guid>
			<comments>http://www.imaginanet.com/blog/galeria-de-fotos-polaroid-solo-usando-css-3.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Wed,  2 Dec 2009 10:55:49 +0100</pubDate>
					<category><![CDATA[Web 2.0]]></category>
					<category><![CDATA[JavaScript]]></category>
					<category><![CDATA[CSS]]></category>
					<category><![CDATA[jQuery]]></category>
					<description><![CDATA[Viendo la galer&iacute;a de fotos con estilo polaroid que han creado en el blog de Tutorialzine, la cual utiliza jQuery y un m&iacute;nimo CSS3, que es una sombra "box-shadow" y una rotaci&oacute;n que utiliza "-webkit-transform". As&iacute; hemos creado una galer&iacute;a de fotos similar pero que &uacute;nicamente utiliza CSS 3,...]]></description>
			<content:encoded><![CDATA[>Viendo la galer&iacute;a de fotos con estilo polaroid que han creado en el <a title="Abrir en ventana nueva" href="http://tutorialzine.com/2009/11/hovering-gallery-css3-jquery/" target="_blank">blog de Tutorialzine</a>, la cual utiliza jQuery y un m&iacute;nimo CSS3, que es una sombra "box-shadow" y una rotaci&oacute;n que utiliza "-webkit-transform". <br />As&iacute; hemos creado una galer&iacute;a de fotos similar pero que &uacute;nicamente utiliza CSS 3, pero aplicando las diferentes opciones que permite este.<br /><br />El c&oacute;digo XHTML creado, &uacute;nicamente consta de una lista de im&aacute;genes (ul &gt; li) con su respectivo pie de imagen:
<pre class="code"><ul class="thumb">
    <li>
        <img src="/imaginanet/images/photo_1.jpg" alt="" width="480" height="340" />Globos
    </li>
    <li>
        <img src="/imaginanet/images/photo_2.jpg" alt="" width="480" height="332" />Coche
    </li>
    <li>
        <img src="/imaginanet/images/photo_3.jpg" alt="" width="480" height="321" />Niebla
    </li>
    <li>
        <img src="/imaginanet/images/photo_4.jpg" alt="" width="480" height="315" />Molino de viento
    </li>
    <li>
        <img src="/imaginanet/images/photo_5.jpg" alt="" width="480" height="324" />Bosque
    </li>
</ul>
</pre>
La hoja de estilos, la teneis <a title="Ver hoja de estilo en ventana nueva" href="/blog_files/css/galeria-polaroid.css" target="_blank">aqu&iacute;</a>, en ella, lo m&aacute;s destacable es:<br />Por un lado, tenemos el contenedor de todas las im&aacute;genes (UL), al cual le aplicamos un gradiente de fondo utilizando "<em>-webkit-gradient</em>" en la propiedad "<em>background</em>" del elemento. Aplicamos un gradiente circular o radial con una posici&oacute;n y tama&ntilde;o, que va de un gris m&aacute;s oscuro, a un gris m&aacute;s claro.
<pre class="code css">ul.thumb {
   position: relative;
   list-style: none;
   background: -webkit-gradient(radial, 45 45, 50, 50 10, 640, from(#555), to(#222)) !important;
   background: #666;
}
</pre>
<br />Tambi&eacute;n tenemos el posicionamiento y la rotaci&oacute;n que damos a cada LI, con su respectiva imagen y texto. Posicionamos el elemento centrado tanto en altura como en anchura, lo redimensionamos y le aplicamos sombra, adem&aacute;s, es importante tener en cuenta que este elemento tiene un efecto "ease-in-out" en el "-webkit-transition" con una duraci&oacute;n de 3 segundos, es el que hace que en WebKit, se amplien y reduzcan con el efecto de zoom . Adem&aacute;s, con el selector "<em>:nth-child()</em>", cambiamos la posici&oacute;n y giramos cada imagen, adem&aacute;s de aplicar a cada imagen una sombra.<br />
<pre class="code css">ul.thumb li {
   position: absolute;
   top: 50%;
   left: 50%;
   padding: 6px 6px 24px 6px;
   background: #FFF;
   width: 150px;
   height: 130px;
   -moz-box-shadow:1px 1px 6px #222;
   -webkit-box-shadow:1px 1px 6px #222;
   box-shadow:1px 1px 6px #222;
   -webkit-transition: all 3s ease-in-out;
   z-index: 0;
}
ul.thumb li img {
   width: 100%;
   height: 100%;
}
ul.thumb li:nth-child(1) {
   margin-top: -130px;
   margin-left: -130px;
   -moz-transform: rotate(30deg);
   -webkit-transform: rotate(30deg);
   transform: rotate(30deg);
}
</pre>
<br />Para terminar, tambi&eacute;n es muy destacable el estilo que aplicamos al estado ":hover" de cada imagen, en este, utilizamos "-webkit-transform" para cambiar la rotaci&oacute;n y poner la imagen completamente horizontal:
<pre class="code css">ul.thumb li:hover{
   font-size: 1.3em;
   z-index: 10;
   width: 480px;
   height: 322px;
   margin-top: -151px;
   margin-left: -240px;
   -moz-box-shadow:8px 8px 24px #111;
   -webkit-box-shadow:8px 8px 24px #111;
   box-shadow:8px 8px 24px #111;
   -moz-transform: rotate(0deg);
   -webkit-transform: rotate(0deg);
   transform: rotate(0deg);
}
</pre>
<br />La galer&iacute;a de fotos <a title="Ver demo de galer&iacute;a" href="/blog_files/galeria-polaroid.htm" target="_blank">podeis visualizarla aqu&iacute;</a> y es &uacute;nicamente funcional desde FireFox 3.5 (no veremos efecto de ampliaci&oacute;n alguno) y desde navegadores utilizando &uacute;ltimas versiones de WebKit, como por ejemplo Safari y Google Chrome (en estos, el efecto de ampliaci&oacute;n funciona gracias a -webkit-transition).<br /><br />La raz&oacute;n por la que no funcionar&aacute; en Internet Explorer (cualquier versi&oacute;n), es que este, ni en su &uacute;ltima versi&oacute;n cumple con el estandar CSS 3, por ejemplo, el selector :nth-child(N) no es reconocido por IE.<br />]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=7</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/galeria-de-fotos-polaroid-solo-usando-css-3.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Lo más buscado durante 2009</title>
			<link>http://www.imaginanet.com/blog/lo-mas-buscado-durante-2009.html</link>
			<guid>http://www.imaginanet.com/blog/lo-mas-buscado-durante-2009.html</guid>
			<comments>http://www.imaginanet.com/blog/lo-mas-buscado-durante-2009.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Wed,  2 Dec 2009 17:39:31 +0100</pubDate>
					<category><![CDATA[Buscadores]]></category>
					<category><![CDATA[Google]]></category>
					<description><![CDATA[Se ha publicado la informaci&oacute;n con las palabras que m&aacute;s se han buscado o consultado en los motores de b&uacute;squeda m&aacute;s populares.Como seguro que a cada uno le interesa una cosa distinta, os dejo una lista de enlaces a cada uno de los casos:AOLAskBingGoogle Espa&ntilde;aGoogleYahoo!Yahoo! Respuestas]]></description>
			<content:encoded><![CDATA[>Se ha publicado la informaci&oacute;n con las palabras que m&aacute;s se han buscado o consultado en los motores de b&uacute;squeda m&aacute;s populares.<br /><br />Como seguro que a cada uno le interesa una cosa distinta, os dejo una lista de enlaces a cada uno de los casos:<br /><a title="Abrir en una ventana nueva" href="http://hot.aol.com/" target="_blank">AOL</a><br /><a title="Abrir en una ventana nueva" href="http://sp.ask.com/2009/topquestions" target="_blank">Ask</a><br /><a title="Abrir en una ventana nueva" href="http://www.bing.com/community/blogs/search/archive/2009/11/30/top-bing-searches-in-2009.aspx" target="_blank">Bing</a><br /><a title="Abrir en una ventana nueva" href="http://www.google.com/intl/es_es/press/zeitgeist2009/index.html" target="_blank">Google Espa&ntilde;a</a><br /><a title="Abrir en una ventana nueva" href="http://www.google.com/intl/en_us/press/zeitgeist2009/index.html" target="_blank">Google</a><br /><a title="Abrir en una ventana nueva" href="http://yearinreview.yahoo.com/" target="_blank">Yahoo!</a><br /><a title="Abrir en una ventana nueva" href="http://yanswersblog.com/index.php/archives/2009/11/30/download-the-2009-answers-highlights-book/" target="_blank">Yahoo! Respuestas</a><br />]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=10</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/lo-mas-buscado-durante-2009.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Aumenta la longitud de búsqueda. Sobre todo en Google.</title>
			<link>http://www.imaginanet.com/blog/aumenta-la-longitud-de-busqueda--sobre-todo-en-google-.html</link>
			<guid>http://www.imaginanet.com/blog/aumenta-la-longitud-de-busqueda--sobre-todo-en-google-.html</guid>
			<comments>http://www.imaginanet.com/blog/aumenta-la-longitud-de-busqueda--sobre-todo-en-google-.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Wed,  2 Dec 2009 12:18:42 +0100</pubDate>
					<category><![CDATA[Buscadores]]></category>
					<category><![CDATA[SEO]]></category>
					<description><![CDATA[En el blog que Alan Long tiene en Hitwise, han sacado un nuevo estudio sobre la longitud de las b&uacute;squedas en los distintos buscadores web.En el informe se ve c&oacute;mo la longitud de las frases de b&uacute;squeda est&aacute; aumentando paulatinamente, y sobre todo, donde m&aacute;s est&aacute; aumentando es en Google....]]></description>
			<content:encoded><![CDATA[>En el blog que <a title="Ver en ventana nueva" href="http://weblogs.hitwise.com/alan-long/2009/11/searches_getting_longer.html" target="_blank">Alan Long tiene en Hitwise</a>, han sacado un nuevo estudio sobre la longitud de las b&uacute;squedas en los distintos buscadores web.<br /><br />En el informe se ve c&oacute;mo la longitud de las frases de b&uacute;squeda est&aacute; aumentando paulatinamente, y sobre todo, donde m&aacute;s est&aacute; aumentando es en Google. Esto &uacute;ltimo nos lleva a pensar si realmente esto est&aacute; asociado a la cada vez menor calidad de los resultados que obtenemos al realizar b&uacute;squedas con el buscador.<br />Y es que la larga cola est&aacute; comenzando a entrar en la mente de los usuarios, que pasan de querer algo poco definido a realizar consultas cada vez m&aacute;s elaboradas para llegar a la informaci&oacute;n que realmente quieren conseguir.<br /><br />El informe, adem&aacute;s de otros detalles, nos revela que la longitud de las consultas ha aumentado poco a poco con el paso del tiempo, y conforme aumenta el n&uacute;mero de personas que se erigen como profetas del posicionamiento en buscadores, y &uacute;nicamente buscan un posicionamiento, pero que para nada creo que se pueda llamar org&aacute;nico, sino posicionamiento que &uacute;nicamente genere tr&aacute;fico. No importa si el tr&aacute;fico generado es de buena, mediana o mala calidad.<br /><br />En mi opini&oacute;n, la longitud de b&uacute;squeda aumenta por una simple raz&oacute;n, los resultados tienen mucho posicionamiento, aunque el posicionamiento lo &uacute;nico que busque sea el click y no el cliente de calidad, esto, hace que los resultados iniciales tengan cada vez menos relevancia, y el usuario cada vez tenga que aumentar el n&uacute;mero de palabras de b&uacute;squeda para hacerla m&aacute;s espec&iacute;fica para lo que est&aacute; buscando.<br /><br />Tengo que decir adem&aacute;s, que es curioso ver c&oacute;mo la calidad del tr&aacute;fico generado por otros buscadores como puede ser Yahoo, es mucho mejor, y los usuarios captados a trav&eacute;s de estos, tienen un perfil de usuario que se ajusta much&iacute;simo mejor al perfil deseado.<br /><br />Para terminar, os incluyo una tabla resumen de las longitudes de b&uacute;squeda:<br /><br /><img title="Longitud de la cadena de b&uacute;squeda, tabla resumen." src="http://www.imaginanet.com/blog_files/images/srchtermlenght_xtended.png" alt="Longitud de la cadena de b&uacute;squeda, tabla resumen." /><br /><br /><br />El siguiente gr&aacute;fico muestra la longitud media de b&uacute;squeda, para todos los buscadores en general:<br /><br /><a onclick="window.open('/blog_files/images/searchtermlength.png','popup','width=849,height=450,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false" href="/blog_files/images/searchtermlength.png"><img title="Longitud de la cadena de b&uacute;squeda, media para todos los buscadores." src="http://www.imaginanet.com/blog_files/images/searchtermlength_small.png" alt="Longitud de la cadena de b&uacute;squeda, media para todos los buscadores." /></a><br /><br /><br />Mientras que en la siguiente, se muestra para los buscadores m&aacute;s importantes. En &eacute;l se puede apreciar c&oacute;mo dependiendo del buscador, hay bastante diferencia en longitudes de cadena de b&uacute;squeda:<br /><br /><a onclick="window.open('/blog_files/images/sengines_length.png','popup','width=849,height=450,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false" href="/blog_files/images/sengines_length.png"><img title="Longitud de la cadena de b&uacute;squeda, principales buscadores." src="http://www.imaginanet.com/blog_files/images/sengines_length_sml.png" alt="Longitud de la cadena de b&uacute;squeda, principales buscadores." width="429" height="222" /></a>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=8</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/aumenta-la-longitud-de-busqueda--sobre-todo-en-google-.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Haciendo páginas web atractivas y usables.</title>
			<link>http://www.imaginanet.com/blog/haciendo-paginas-web-atractivas-y-usables.html</link>
			<guid>http://www.imaginanet.com/blog/haciendo-paginas-web-atractivas-y-usables.html</guid>
			<comments>http://www.imaginanet.com/blog/haciendo-paginas-web-atractivas-y-usables.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Tue, 24 Nov 2009 10:05:37 +0100</pubDate>
					<category><![CDATA[Web 2.0]]></category>
					<category><![CDATA[XHTML]]></category>
					<category><![CDATA[CSS]]></category>
					<category><![CDATA[Ajax]]></category>
					<description><![CDATA[El presente artículo ha sido traducido del publicado en http://www.lazycat.org/postcards/  Diseños abiertos y elegantes, menores costes de ancho de banda y un mantenimiento mucho más fácil. ¿Os gusta la idea? Leed este artículo para conocer pequeños trucos que puedes aplicar al código, diseño y contenidos de tus páginas...]]></description>
			<content:encoded><![CDATA[><p style="display: inline; float: left;"><img style="display: inline; float: left; margin-right: 10px;" title="Haciendo páginas web atractivas y usables." src="/ftp/articulos_web/nakkeTattis.jpg" alt="Haciendo páginas web atractivas y usables." width="232" height="310" /> El presente artículo ha sido traducido del publicado en <a href="http://www.lazycat.org/postcards/">http://www.lazycat.org/postcards/</a><br /> <br /> Diseños abiertos y elegantes, menores costes de ancho de banda y un mantenimiento mucho más fácil.<br /> <br />¿Os gusta la idea? Leed este artículo para conocer pequeños trucos que puedes aplicar al código, diseño y contenidos de tus páginas web, y si alguno de los sitios web que visitas normalmente no da la talla, ¿porqué no comentarles que pueden hacer un cambio limpio, rápido y con muchas ventajas sobre lo que tiene?<br /> <br />Muchas páginas web incluyen enlaces a artículos relacionados y más información. Envíales URLs que creas les puedan ayudar y pienses que son útiles.</p>
<h3>Hojas de estilo alternativas</h3>
Son distintos puntos de vista. Añadir la posibilidad de visualizar una página web en formato impreso, o por ejemplo, en terminales de mano (pocket pc, palm os, ...), hacen que un sitio web sea visible por una mayor audiencia y así, aumente la satisfacción del cliente. De esta forma, los usuarios no tienen porque buscar una versión para imprimir (si existe claro) ya que las hojas de estilo para imprimir se cargan de forma automática en cualquier navegador web. <br /> Si está vendiendose algo, una disposición dedicada a la impresión, ahorra el esfuerzo y coste de crear y mantener archivos PDF independientes. Las hojas de estilo para medio impreso, pueden incluir reglas que impriman las urls junto con los enlaces, expandan los acrónimos y muestren la información de copyright. <br /> Existen hojas de estilo para TV, proyectores, lectores de texto, ... <br />
<h3>Fondos</h3>
Una imagen de fondo puede ser la diferencia entre una página web que atraiga todas las miradas y una página web que genere dolores de tripa. La elección de imagenes que puedan estirarse con el fondo, es esencial, así como el uso de colores apropiados y el hecho de asegurarse de que ls imágenes de fondo permanecen en el fondo.<br /> Si tienes dudas, quítala: un diseño simple y limpio, a veces funciona mejor que un diseño complejo y visualmente rico en grafismos. A veces, una página web diseñada de forma pobre da peor imagen que no tener página web.<br /> Hay que recordad que cualquier elemento puede tener una imagen de fondo o color de fondo si usa CSS, aprovechar esta ventaja permite la construcción de webs ricas en grafismo.<br />
<h3>Elección de los colores</h3>
Con los colores, como con muchas otras cosas, cuanto menos, a veces es mejor. Lo ideal es elegir entre tres y cinco colores para un diseño o para una sección del sitio web si se desea que estas sean distintas.<br /> Hay que ser cuidadoso con las connotaciones de los colores y amoldarlos a la audiencia que se espera atraer. Por ejemplo los visitantes del este pueden estar buscando colores vivos como rojos y amarillos para estar cómodos, por otro lado, los visitantes de occidente los pueden encontrar demasiado chillones para sus ojos e incluso ofencivos. Por ejemplo, Ladbrokes, amolda su esquema de colores a la procedencia de sus visitantes; si quieres una página web global, esta es posible.<br />
<h3>Tablas</h3>
Si todavia alguien está diseñando páginas web con tablas HTML, ¿cuantos años llevas perdido por el mundo? ¿dónde has estado? La comida ya se ha terminado y también te has perdido los postres, esto hace que no conozcas lo fácil y cómodo que puede ser hacer páginas web con CSS (hojas de estilo). Cuando alguien quiere atornillar un tornillo, que usa, ¿un martillo o un destornillador? Por la misma razón, porqué usar tablas HTML para maquetar páginas web. <br /> Es aconsejable diseñar de acuerdo con las especificaciones web estandares del momento, y además, conseguiras mayor control de la maqueta si la haces usando hojas de estilo. Las páginas web modernas estan basadas en los estandards web, cargan mucho más rápido, se ven más bonitas y te harán ahorrar dinero. Si tu jefe se entera de que no has estado cenando, ve pensando la explicación que vas a darle.]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=5</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/haciendo-paginas-web-atractivas-y-usables.html</feedburner:origLink>
		</item>
				
		<item>
			<title>19 consejos para construir páginas web</title>
			<link>http://www.imaginanet.com/blog/19-consejos-para-construir-paginas-web.html</link>
			<guid>http://www.imaginanet.com/blog/19-consejos-para-construir-paginas-web.html</guid>
			<comments>http://www.imaginanet.com/blog/19-consejos-para-construir-paginas-web.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Mon, 23 Nov 2009 20:25:48 +0100</pubDate>
					<category><![CDATA[Web 2.0]]></category>
					<description><![CDATA[Esto significa, que no pretendas re-inventar la navegaci&oacute;n por los sitios web. Pon las cosas a la izquierda, arriba, abajo, donde quieras, pero no reinventes la forma en que la gente interactua con entornos o interfaces digitales si lo que quieres es vender tu marca, tus productos o tus servicios. No confundas al usuario,...]]></description>
			<content:encoded><![CDATA[>Esto significa, que no pretendas re-inventar la navegaci&oacute;n por los sitios web. Pon las cosas a la izquierda, arriba, abajo, donde quieras, pero no reinventes la forma en que la gente interactua con entornos o interfaces digitales si lo que quieres es vender tu marca, tus productos o tus servicios. No confundas al usuario, puede sentirse mal y abandonar la web.<br />
<h3>Introducci&oacute;n</h3>
Este art&iacute;culo se ha extraido del original (<a href="http://www.josiahcole.com/2007/02/14/a-webmasters-19-commandments/">click aqu&iacute;</a>) titulado <a href="http://www.josiahcole.com/2007/02/14/a-webmasters-19-commandments/"><em>19 Things NOT To Do When Building a Website</em></a><em>.</em> El art&iacute;culo es muy did&aacute;ctico y creemos que expone cada uno de los casos con criterio y desde el punto de vista de la usabilidad.<br /> El autor ha recopilado una peque&ntilde;a lista de reglas b&aacute;sicas y fundamentales que todo webmaster debe tener en cuenta a la hora de desarrollas un sitio web que pretenda llegar a su p&uacute;blico con un m&iacute;nimo de &eacute;xito. Esta lista tambi&eacute;n pueden usarla las empresas que esten pensando en la creaci&oacute;n o re-estructuraci&oacute;n de su sitio web.<br />
<h3>No redimensionar la ventana del navegador</h3>
No cambiar el tama&ntilde;o de la ventana del navegador del usuario. Todos sabemos que se puede modificar el tama&ntilde;o de la ventana del usuario, y sabemos lo bien que uno se siente cuando tras poner un peque&ntilde;o trozo de c&oacute;digo Javascript ocurre un <em>milagro</em> que redimensiona la ventana al tama&ntilde;o que queremos, pero NO. Esta mala t&eacute;cnica web se ve en la mayor&iacute;a de casos con sitios web denominados <em>spam</em> o cuando un dise&ntilde;ador gr&aacute;fico no acostumbrado al entorno web, dise&ntilde;a un sitio web, es decir, alguien del sector de la fotograf&iacute;a, video o art&iacute;stico que tambi&eacute;n hace sitios web (ver consejo n&uacute;mero 6 para conocer m&aacute;s cosas sobre estos), pero a decir verdad no tiene idea alguna de c&oacute;mo crear un web exitoso y usable.<br /><img title="No redimensionar la ventana del navegador" src="http://farm1.static.flickr.com/150/391487797_e7749ccade.jpg?v=0" alt="No redimensionar la ventana del navegador" width="325" height="294" /><br />
<h3>Si quieres cargar una home, y a continuaci&oacute;n tu web en un pop-up, para nada te lo recomendamos.</h3>
Si tu web necesita que el visitante carge una p&aacute;gina de inicio y entonces acceda a la verdadera p&aacute;gina web en un pop up (ventana emergente), estas mareando al usuario, le das la bienvenida pero no es as&iacute;, le vuelves a dar la bienvenida. Si tu web no carga de forma inmediata con un inicio que aporte valor al visitante, es muy dificil que espere a que termine tu show de inicio (no le preocupa lo bonita y espectacular que es la p&aacute;gina de introducci&oacute;n). Esta t&eacute;cnica se ve con la mayor&iacute;a de desarrolladores web con Flash, los cuales, por alguna raz&oacute;n piensan que todos los sitios web en flash tienen que abrirse en una ventana emergente (estan dando por hecho que burlan los programas que bloquean ventanas emergentes) y tienen 30 segundos de carga de una introducci&oacute;n como <a href="http://www.2advanced.net/" target="_blank">www.2advanced.net</a><br />
<h3>Si preguntas que versi&oacute;n quieres: versi&oacute;n flash, html, alta resoluci&oacute;n, baja resoluci&oacute;n. Tambi&eacute;n pierdes oportunidad.</h3>
<p>Es como si le preguntases a alguien que quiere entrar en tu tienda, si quiere pasar a la tienda mala o a la buena (pero claro, hay que tener en cuenta que para entrar en la tienda buena hacen falta unas gafas especiales y una peque&ntilde;a espera de 30 segundos... MMM, NO gracias), lo que les estas preguntando es: "&iquest;Quieres irte y comprar en mi competencia? porque te estoy poniendo una muralla que tienes que saltar antes de que conozcas los productos o servicios que te ofrezco.</p>
<h3>Si tienes una web, toda en flash, hazla de nuevo.</h3>
Si tu web est&aacute; toda en Flash, echa a tu dise&ntilde;ador web y si la hiciste t&uacute;, a&ntilde;&aacute;dela a tu curriculum bajo la secci&oacute;n de "Proyectos sin utilidad que he realizado" y empieza de nuevo a hacer la web.&nbsp;<br /> Flash es una herramienta, una herramienta con much&iacute;simas posibilidades como animaciones, v&iacute;deo, carritos de la compra, interfaces, etc, la lista es muy grande pero las cosas en su medida. Esto no quiere decir que tengas que hacer un sitio web todo en Flash y si lo haces tendr&aacute;s una gran desventaja con tu competencia. F&iacute;jate en una cosa, hasta el propietario de Flash, <a href="http://www.adobe.com/">Macromedia/Adobe</a> no tiene su web toda en Flash, &iquest;sabes porqu&eacute;? Quieren hacer negocio y no hacen caso a los <em>dise&ntilde;adores</em>.<br /><img title="No hagas una web toda en flash" src="http://farm1.static.flickr.com/132/391506482_f6a6bdc635.jpg?v=0" alt="No hagas una web toda en flash" width="450" height="415" /><br />
<h3>NO intentes REinventar la navegaci&oacute;n por p&aacute;ginas web</h3>
<p>Situa los elementos gr&aacute;ficos en la zona de tu p&aacute;gina web que quieras, ponlos arriba, a la izquierda, tambi&eacute;n en la parte derecha puedes colocar elementos, pero sobre todo, no inventes la l&oacute;gica de navegaci&oacute;n, esto es, la manera en que las personas interactuan con interfaces digitales, a la misma vez que est&aacute;s intentando vender un producto o servicios. El usuario se confundir&aacute;, se enfadar&aacute;, y se ir&aacute;.</p>
<h3>&nbsp;Este trabajo me va a dar bastantes dolores de cabeza</h3>
<p>Si eres un dise&ntilde;ador gr&aacute;fico, y "de paso ofreces p&aacute;ginas web", estas dando consejos sobre dise&ntilde;o web, a tus clientes de trabajos gr&aacute;ficos impresos, se cauto con este tema. El dise&ntilde;o gr&aacute;fico para impresi&oacute;n se parece al dise&ntilde;o web lo mismo que un anuncio de un coche de carreras a conducir y construir ese coche de carreras. No cometamos errores, el dise&ntilde;o gr&aacute;fico es fant&aacute;stico por si mismo, sabes hacer gr&aacute;ficas perfectas y perfectos slogans para impresi&oacute;n. Un usuario no puede comprarte el producto con un anuncio impreso (por el momento), no pueden comunicarse con tu negocio a trav&eacute;s de un anuncio impreso. Ded&iacute;cate al dise&ntilde;o gr&aacute;fico y no metas tus narices en un medio que no conoces ni entiendes (lo mismo les digo a esos "t&eacute;cnicos" que haces websites "aprovechando la situaci&oacute;n")</p>
<h4>Si una p&aacute;gina de inicio no tiene contenido o cualquier texto Real (no incluido en una imagen) y esto mismo es extensible a todo el sitio web. Contrata a una persona que dote de contenido a la p&aacute;gina web y despide a tu webmaster.</h4>
<p>El contenido es el rey. Los buscadores no indexan gr&aacute;ficos o animaciones flash deslumbrantes, s&oacute;lo indexan texto. Contrata una persona que de contenidos relevantes y vinculados con tu negocio (es b&aacute;sico para tener un buen ranking y poder vender / ofrecer tus productos o servicios a trav&eacute;s de una p&aacute;gina web)</p>
<h4>Si tu p&aacute;gina web no funciona con Firefox, da la bienvenida a la metedura de pata m&aacute;s com&uacute;n de 2007.</h4>
<p>Realmente, Firefox s&oacute;lo genera entre el 10-15% de la cuota de mercado de los navegadores de usuario, pero en el caso de algunos sitios web, esta cuota es mucho m&aacute;s alta, por ejemplo, oomny.com tiene m&aacute;s del 80% de sus usuarios con Firefox. Adem&aacute;s, si quien hizo tu p&aacute;gina web, no la hizo compatible y funcional con Firefox, obviamente no tienen idea de lo que est&aacute;n haciendo y se est&aacute;n saliendo del juego. No hay raz&oacute;n por la que se necesite un sitio web s&oacute;lo compatible y totalmente dependiente de Internet Explorer para que no funcione en Firefox, y francamente, no hay raz&oacute;n alguna para ello. Que un webmaster no conozca Firefox, quiere decir que no est&aacute; en la cultura de Internet y esto puede hacer que tu imagen y la de tu negocio en Internet se vean afectados.</p>
<h3>Este punto es una colecci&oacute;n de peque&ntilde;as cosas que han hecho desaparecer a otros sitios web.</h3>
<p>Son principios b&aacute;sicos pero repetidos, como no mostrar texto parpadeante, no usar Frontpage, no utilizar pop-ups o ventanas emergentes, no hacer texto con scroll, obligar a la descarga de fuentes o tipograf&iacute;as especiales, utilizar introducciones Flash, ...</p>
<h3>Si utilizas m&uacute;sica en tu p&aacute;gina web cerciorarte de que el usuario pueda detenerla,</h3>
<p>y es MEJOR NO cargarla con la p&aacute;gina web sin que la solicite el usuario. Esto mismo, es aplicable al v&iacute;deo con audio, muchos usuarios de p&aacute;ginas web navegan desde su trabajo y no les hace mucha gracia que sus altavoces empiecen a sonar con tu espantosa m&uacute;sica de forma totalmente intrusiva en su ordenador, y m&aacute;s si su jefe est&aacute; pendiente y con ganas de darle a alguien una patada en el trasero.</p>]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=4</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/19-consejos-para-construir-paginas-web.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Activado automático de componentes en IE (Actualización de los cambios en componentes ActiveX de IE)</title>
			<link>http://www.imaginanet.com/blog/activado-automatico-de-componentes-en-ie-actualizacion-de-los-cambios-en-componentes-activex-de-ie.html</link>
			<guid>http://www.imaginanet.com/blog/activado-automatico-de-componentes-en-ie-actualizacion-de-los-cambios-en-componentes-activex-de-ie.html</guid>
			<comments>http://www.imaginanet.com/blog/activado-automatico-de-componentes-en-ie-actualizacion-de-los-cambios-en-componentes-activex-de-ie.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Thu, 29 Oct 2009 13:28:38 +0100</pubDate>
					<category><![CDATA[Internet Explorer]]></category>
					<category><![CDATA[Navegadores]]></category>
					<category><![CDATA[ActiveX]]></category>
					<description><![CDATA[Si miramos a abril de 2006, hicimos un cambio en la forma en que Internet Explorer manejaba los controles incrustados (embed) en bastantes p&aacute;ginas web. Algunos sitios web obligaban a los usuarios a "pulsar para activar" antes de que pudieran interactuar con el control. A dia de hoy, Microsoft ha obtenido la licencia de...]]></description>
			<content:encoded><![CDATA[>Si miramos a abril de 2006, hicimos un cambio en la forma en que Internet Explorer manejaba los controles incrustados (embed) en bastantes p&aacute;ginas web. Algunos sitios web obligaban a los usuarios a "pulsar para activar" antes de que pudieran interactuar con el control. A dia de hoy, Microsoft ha obtenido la licencia de Eolas, eliminando con esta el requisito de Internet Explorer de "pulsa para activar". Por esto, vamos a quitar el comportamiento "pulsar para activar el control" que ahora tiene IE.<br /> <br /> Es importante tener en cuenta que este cambio no necesitar&aacute; que se modifiquen&nbsp;las p&aacute;ginas web existentes hoy en d&iacute;a , ni acciones nuevas a tomar por parte de quienes crean y desarrollan p&aacute;ginas web. Simplemente estamos retrocediendo al comportamiento anterior. Una vez se actualice Internet Explorer, todas las p&aacute;ginas que ahora necesitan del "pulsar para activar" dejar&aacute;n de necesitarlo para que el control se active. Simplemente funcionar&aacute;. <br /> <img src="/ftp/articulos_web/activex_ie/clicktoactivate.png" alt="" /><br />Lo m&aacute;s normal es que actualmente te preguntes para cuando est&aacute; previsto lanzar esta actualizaci&oacute;n.<br /> <br /> La primera versi&oacute;n en pruebas, saldr&aacute; con una actualizaci&oacute;n opcional llamada Activaci&oacute;n de Componentes Autom&aacute;tica para Internet Explorer (Internet Explorer Automatic Component Activation Preview), y estar&aacute; disponible en Diciembre de 2007 en el Centro de Descargas de Microsoft. Adem&aacute;s, este cambio formar&aacute; parte de las pr&oacute;ximas versi&oacute;nes pre-release de Windows Vista SP1 y Windows XP SP3. Despu&eacute;s de haber dado tiempo a que los usuarios se preparen para este cambio, haremos que este comportamiento forme parte de la "Cumulative Update" de Internet Explorer en Abril de 2008, as&iacute;, todos los clientes que instalen esta actualizaci&oacute;n, aplicar&aacute;n este cambio a su IE.<br /> <br /> Si tienes una aplicaci&oacute;n a medida usando WebOC o MSHTML, habr&aacute; algunos cambios que afectar&aacute;n tu aplicaci&oacute;n. Por ejemplo:<br /> - Si la aplicaci&oacute;n usa el flag&nbsp;DOCHOSTUI para el "pulsar para activar", ese comportamiento se respetar&aacute; y tu aplicaci&oacute;n seguir&aacute; necesitando del "pulsar para activar".<br /> - Si la aplicaci&oacute;n usa la clave del registro FEATURE_ENABLE_ACTIVEX_INACTIVE_MODE para optar por el "pulsar para activar", esta clave de registro no ser&aacute; mantenida. Si quieres seguir utilizando el "pulsar para activar", por favor, utilliza el flag DOCHOSTUI.<br /> <br /> En las pr&oacute;ximas semanas actualizaremos en <a href="http://msdn.microsoft.com/ieupdate">art&iacute;culo en MSDN</a> con las descripciones del nuevo comportamiento. Estate atento en este enlace para saber cuando sale la preview.<br />]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=2</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/activado-automatico-de-componentes-en-ie-actualizacion-de-los-cambios-en-componentes-activex-de-ie.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Haciendo funcionar a las hojas de estilos alternativas</title>
			<link>http://www.imaginanet.com/blog/haciendo-funcionar-a-las-hojas-de-estilos-alternativas.html</link>
			<guid>http://www.imaginanet.com/blog/haciendo-funcionar-a-las-hojas-de-estilos-alternativas.html</guid>
			<comments>http://www.imaginanet.com/blog/haciendo-funcionar-a-las-hojas-de-estilos-alternativas.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Tue, 20 Oct 2009 12:35:41 +0100</pubDate>
					<category><![CDATA[JavaScript]]></category>
					<category><![CDATA[CSS]]></category>
					<description><![CDATA[Autor Original: Paul Sowden  URL ORIGINAL: http://www.alistapart.com/stories/alternate/  TÍTULO ORIGINAL: A List Apart: CSS: Making Alternate Style Sheets Work  Traducción al castellano: http://kusor.net/traducciones/ala.es/alternate/  Así, TIENES UN DOCUMENTO XHTML. Has sido un diseñador web bueno y utilizado hojas de estilos...]]></description>
			<content:encoded><![CDATA[><em><span style="text-decoration: underline;">Autor Original</span>: Paul Sowden <br /> <span style="text-decoration: underline;">URL ORIGINAL</span>: http://www.alistapart.com/stories/alternate/ <br /> <span style="text-decoration: underline;">TÍTULO ORIGINAL</span>: A List Apart: CSS: Making Alternate Style Sheets Work <br /> <span style="text-decoration: underline;">Traducción al castellano</span>: http://kusor.net/traducciones/ala.es/alternate/</em><br /> <br /> Así, TIENES UN DOCUMENTO XHTML. Has sido un diseñador web bueno y utilizado hojas de estilos para controlar el aspecto de tu documento. Incluso has ido mucho más allá y has creado varias hojas de estilo alternativas para demostrar lo duro que eres. <br /> <br /> Estupendo. Pero ahora necesitas un modo cross–browser de elegir dinámicamente entre las distintas hojas de estilos. <br /><br />
<h3>Dándole estilo a tu sitio</h3>
Las hojas de estilos pueden ser asociadas con los documentos usando una lista de elementos link en la cabecera del documento. Hay tres tipos de relación distintos que pueden tener las hojas de estilos externas con el documento: persistentes, preferridas, y alternativas.<br />
<h4>Persistentes</h4>
Estas hojas de estilos están habilitadas siempre (siempre están “encendidas”) y son combinadas con la hoja de estilos activa. Pueden utilizarse para compartir reglas comunes a todas las hojas de estilos. Para hacer una hoja de estilos persistente, el atributo rel es fijado a “stylesheet” y no se fija ningún atributo title. <br /> <br /> Para hacer persistente la hoja de estilos paul.css, el siguente elemento link debería ser incluido en la cabecera del documento:
<h4>Preferidas</h4>
Estas hojas de estilo están habilitadas por defecto (están “encendidas” cuando se ha cargado la página). Pueden ser deshabilitadas entonces, si el usuario eleige una hoja de estilos alternativa. <br /> <br /> Para hacer una hoja de estilos preferida, el atributo rel se fija a “stylesheet” y a la hoja de estilos se le asigna un nombre con el atributo title. <br /> <br /> Varias hojas de estilo preferidas pueden ser agrupadas dándoles atributos title idénticos. Estas hojas de estilos agrupadas serán entonces habilitadas y deshabilitadas juntas. Si se declara más de un grupo de hojas de estilo preferidas, el primero que se declare tendrá preferencia. <br /> <br /> Para hacer preferida a paul.css, es añadido un atributo title, dándole al estilo por defecto un nombre.<br />
<h4>Alternativas</h4>
Estas hojas de estilo pueden ser seleccionadas por el visitante como alternativas a la hoja de estilos preferida. Esto permite al visitante personalizar un sitio y elegir su disposición favorita. También pueden ser utilizadas para accesibilidad (por ejemplo, ALA tiene la hoja de estilos “friendly fonts” que proporciona fuentes mayores). <br /> <br /> Para especificar una hoja de estilos alternativa, el atributo rel se fija a “alternate stylesheet” y la hoja de estilos se nombra con un atributo title. Como pasa con las hojas de etilo preferidas, estas hojas de estilos pueden ser agrupadas juntas también dándoles atributos title idénticos. <br /> <br /> Usando de nuevo el ejemplo previo; para convertir paul.css en una hoja de estilos alternativa, la palabra “alternate” es añadida al atributo rel.<br /> Notar que estas relaciones sólo se aplican a hojas de estilo externas que hayan sido incluidas usando el elemento link.<br />
<h3>Intercambiando estilos</h3>
Cuando un documento es cargado inicialmente, las hojas de estilo persistentes y preferidas son aplicadas al documento. Las hojas de estilo alternativas pueden ser seleccionadas por el usuario. El W3C nos dice que el navegador debería proporcionarnos un medio de elegir la hoja de estilos que queremos utilizar, y sugiere que quizá un menú sesplegable o un abarra de herramientas debería ser proporcionada. <br /> <br /> Hasta aquí, muy bien. Tenemos varias hojas de estilos y el visitante puede elegir sus favoritas desde un menú. Pero entonces nos encontramos con un prolema. Uno importante. Mozilla proporciona un menú para seleccionar las hojas de estilos que queremos usar bajo un item del menú ver. Pero Microsoft Internet Explorer (MSIE) no proporciona ningún menú. Por lo que tenemos varias hojas de estilos, y ningún modo de acceder a ellas en MSIE. <br /> <br /> Aquí es donde un poco de JavaScript puede ser utilizado junto con el DOM para proporcionar un modo mediante el cuál los usuarios de MSIE y Mozilla puedan seleccionar la hoja de estilos que quieran utilizar. Sus preferencias pueden guardarse también en una cookie. Y como estamos utilizando las etiquetas link tal como nos dice el W3C, JavaScript no va a interferir con el menú en Mozilla, y va a degradar grácilmente. <br />
<h3>El Script</h3>
Primero necesitamos que el script sea capaz de diferenciar entre tres tipos diferentes de hojas de estilo. Esto es relativamente fácil de hacer, dado que sólo necesitamos comprobar dos de los atributos de cada elemento link. <br /> <br /> ¿Hay algún enlace a un elemento link?<br />
<pre class="code">HTMLLinkElement.getAttribute("rel").indexOf("style") != -1 </pre>
¿Hay un atributo title?
<pre class="code">HTMLListElement.getAttribute("title")</pre>
¿Contiene el atributo rel la palabra clave "alternate"?
<pre class="code">HTMLLinkElement.getAttribute("rel").indexOf("alt") != -1</pre>
Notar que estamos buscando la cadena “alt” porque algunos navegadores aceptan la palabra reservada “alternative” en lugar de “alternate.” <br /> <br /> Usando estos tres tipos de chequeo podemos escribir una función para elegir las hojas de estilos. Esto implica buscar todos los elemoentos link en el documento, deshabilitando todas las hojas de estilo preferidas y alternativas que no queremos que estén activas, y habilitando todas las hojas de estilo preferidas y alternativas que queremos que estén activas. <br /> <br /> Notar que sólamente los elementos link de hojas de estilo alternativas y preferidas tendrán un atributo title. <br /> <br /> La función de cambio tiene el aspecto siguiente:
<pre class="code">function setActiveStyleSheet(title) { <br /> var i, a, main; <br />  for(i=0; (a = document.getElementsByTagName("link")[i]); i++) { <br />    if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title")) { <br />     a.disabled = true; <br />     if(a.getAttribute("title") == title) a.disabled = false; <br />    } <br />  } <br />}  </pre>
<h4>Cookies</h4>
Ahora podemos cambiar las hojas de estilo. Estupendo. Tenemos una página más personalizada. Excelente. Pero no tenemos un sitio personalizado. Las preferencias se aplican sólo a la página actual; cuando la dejemos las preferencias se irán con ella. De cualquier modo, esta situaciónpuede ser rectificada con una cookie. <br /> <br /> Para guardar una cookie necesitamos otra función que devuelva la hoja de estilo actual. También necesitamos dos funciones que guarden y lean la cookie. <br /> <br /> Para devolver la hoja de estilo actual buscaremos una hoja de estilo preferida o alternativa que esté activa y miraremos su atributo title. <br /> <br /> Primero buscaremos de nuevo a través de todos los elementos link en el documento. Entoncdes comprobaremos que el link es una hoja de estilo. Si es así, comprobaremos que la hoja de estilo tiene un atributo title. Esto nos dirá que la hoja de estilo es bien preferida, bien alternativa. <br /> <br /> La última comprobación es ver si la hoja de estilo está activa o no. Si las tres búsquedas devuelven verdadero, tendremos la hoja de estilo actual y podremos devolver su atributo title. <br /> <br /> La función terminada tiene este aspecto:
<pre class="code">function getActiveStyleSheet() { <br /> var i, a; <br />   for(i=0; (a = document.getElementsByTagName("link")[i]); i++) { <br />    if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title") && !a.disabled) <br />    return a.getAttribute("title"); <br />   } <br /> return null; <br />} </pre>
Como este es un artículo sobre estilos, y las cookies son un tópico completamente diferente, no voy a explicar las funciones de las cookies aquí, pero si voy a incluirlas para tu conveniencia (estas funciones fueron escritas por el autor de ALA Peter-Paul Koch).
<pre class="code">function createCookie(name,value,days) { <br />   if (days) { <br />    var date = new Date(); <br />    date.setTime(date.getTime()+(days*24*60*60*1000)); <br />    var expires = "; expires="+date.toGMTString(); <br />   } <br />   else expires = ""; <br /> document.cookie = name+"="+value+expires+"; path=/"; <br />} <br /> <br />function readCookie(name) { <br /> var nameEQ = name + "="; <br /> var ca = document.cookie.split(';'); <br />    for(var i=0;i < ca.length;i++) { <br />     var c = ca[i]; <br />     while (c.charAt(0)==' ') c = c.substring(1,c.length); <br />     if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length); <br />    } <br /> return null; <br />} </pre>
Para usar estas funciones de cookies, necesitamos agregar onload y onunload event listeners a la ventana.<br />
<h4>onLoad</h4>
Hay un atributo especificado por el w3c DOM Level 2, “disabled,” que se fija a false cuando una hoja de estilos se aplica al documento. Este atributo es implementado correctamente en Mozilla, pero desafortunadamente no lo es en MSIE. <br /> <br /> MSIE tiene un atributo HTML propietario, también llamado “disabled”, que se aplica a los elementos link. Este atribute es fijado inicialmente a false para todos los elementos link. <br /> <br /> Para fijar el atributo disabled de MSIE tal como el atributo disabled del DOM Level 2, podemos llamar a la función setActiveStyleSheet() con el nombre de la hoja de estilo preferida. <br /> <br /> Para encontrar qué hoja de estilo es la preferida, necesitamos otra función. Dado que esta función es bastante similar a la función getActiveStyleSheet() no voy a explicar como funciona, pero aquí está su aspecto:
<pre class="code">function getPreferredStyleSheet() { <br /> var i, a; <br />    for(i=0; (a = document.getElementsByTagName("link")[i]); i++) { <br />     if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("rel").indexOf("alt") == -1 && a.getAttribute("title")) <br />     return a.getAttribute("title"); <br />    } <br /> return null; <br />} </pre>
en la función onload, primero fijamos una variable title. Ésta guardará el valor de la hoja de estilos previa que está almacenada en la cookie, o si no hay ninguna, el título de nuestra hoja de estilos preferida. Para hacer las cosas lógicas, vamos a llamar a la cookie “style.” <br /> <br /> Lo siguiente será llamar a la función setActiveStyleSheet() pasándole la variable title como title. Nuestra función onload será algo parecido a esto:
<pre class="code">window.onload = function(e) { <br />   var cookie = readCookie("style"); <br />   var title = cookie ? cookie : getPreferredStyleSheet(); <br />   setActiveStyleSheet(title); <br />} </pre>
Notar que es muy deseable llamar a esta función antes del evento onload, haciendo al documento que “pinte” con nuestro estilo preferido. <br /> <br /> Si eleiges hacer esto, asegúrate que dicha función es llamada después de haber definido las otras funciones y que los elementos link han sido definidos.<br />
<h4>onUnload</h4>
Guardar la cookie en el evento onunload es simple. Todo lo que tenemos que hacer es usar la función getActiveStyleSheet() para que nos devuelva la hoja de estilos activa, y guardarla en una cookie. Usando la función para guardar una cookie tendríamos finalmente algo como esto:
<pre class="code">window.onunload = function(e) { <br />   var title = getActiveStyleSheet(); <br />   createCookie("style", title, 365); <br />} </pre>
<h3>Juntándolo todo</h3>
Para usar estas funciones para hacer tu sitio web más sexy, necesitas incluirlas en tu documento. Para hacerlo más fácil, las he puesto todas juntas en un fichero javascript, preparado para que lo descargues y lo añadas a tu sitio. <br /> » <a href="http://www.alistapart.com/d/alternate/styleswitcher.js" target="_blank">Descargar styleswitcher.js </a><br /> <br /> Para incluir el fichero javascript, necesitas añadir un elemento script a la cabecera de tu documento, asegurándote de que está puesto después de todos los elementos link pertenecientes a hojas de estilo que tengas. El código HTML debería tener este aspecto:
<pre class="code"><script src="/scripts/styleswitcher.js" type="text/javascript"><!--mce:0--></script> </pre>
Para permitir al visitante cambiar la hoja de estilos activa, podrías usar los eventos onClick de javascript. Por ejemplo, para tener la opción de elegir entre dos temas con los títulos “default” y “paul,” podrías usar el siguiente HTML:
<pre class="code"><a onclick="setActiveStyleSheet('default'); return false;" href="#">change style to default</a> <br /><a onclick="setActiveStyleSheet('paul'); return false;" href="#">change style to paul</a> </pre>
Una vez que el visitante ha seleccionado un tema, éste será almacenado en una cookie. Para usar el mismo tema en todo tu sitio web, los mismos elementos link javascript link deberían ser incluidos en la cabecera de cada página del sitio. <br /> ¡Eso es todo Gente! <br /> <br /> Ahí lo tienes, un sitio web personalizable que utiliza elementos link para enlazar hojas de estilo como el W3C nos ha dicho que deberíamos hacer. ¡Disfrútalo! <br /> <br /> ::: Paul Sowden tiene 17 años (Londres, Inglaterra), y cree que la web sería un lugar mejor si todos usásemos tecnicas de diseño que cumpliesen con los estándares.<br />]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=1</wfw:commentRss>
			<slash:comments>0</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/haciendo-funcionar-a-las-hojas-de-estilos-alternativas.html</feedburner:origLink>
		</item>
				
		<item>
			<title>Arreglando tu página web con el DOCTYPE correcto</title>
			<link>http://www.imaginanet.com/blog/arreglando-tu-pagina-web-con-el-doctype-correcto.html</link>
			<guid>http://www.imaginanet.com/blog/arreglando-tu-pagina-web-con-el-doctype-correcto.html</guid>
			<comments>http://www.imaginanet.com/blog/arreglando-tu-pagina-web-con-el-doctype-correcto.html#comentarios</comments>
			<dc:creator>Imaginanet S.L.</dc:creator>
			<pubDate>Mon, 23 Nov 2009 19:49:19 +0100</pubDate>
					<category><![CDATA[XHTML]]></category>
					<description><![CDATA[Autor Original: Jeffrey ZeldmanURL ORIGINAL: http://www.alistapart.com/articles/doctype/T&Iacute;TULO ORIGINAL: A List Apart: Fixing Your Site With the Right DOCTYPELO HAS HECHO TODO BIEN, pero tu sitio web no tiene el aspecto deseado o funciona como deber&iacute;a hacerlo en los &uacute;ltimos navegadores.Has escrito XHTML y CSS...]]></description>
			<content:encoded><![CDATA[><em><span style="text-decoration: underline;">Autor Original</span>: Jeffrey Zeldman<br /><span style="text-decoration: underline;">URL ORIGINAL</span>: http://www.alistapart.com/articles/doctype/<br /><span style="text-decoration: underline;">T&Iacute;TULO ORIGINAL</span>: A List Apart: Fixing Your Site With the Right DOCTYPE</em><br /><br />LO HAS HECHO TODO BIEN, pero tu sitio web no tiene el aspecto deseado o funciona como deber&iacute;a hacerlo en los &uacute;ltimos navegadores.<br /><br />Has escrito XHTML y CSS v&aacute;lidos. Has utilizado el Modelo de Objetos del Documento (DOM) est&aacute;ndar del W3C para manipular din&aacute;micamente los elementos de la p&aacute;gina. A pesar de todo, en navegadores dise&ntilde;ados para soportar todos estos est&aacute;ndares, tu sitio est&aacute; fallando. Un DOCTYPE - tipo de documento - defectuoso tiene la culpa de ello.<br /><br />Este peque&ntilde;o art&iacute;culo te proporcionar&aacute; DOCTYPEs que funcionen, y explicar&aacute; el efecto pr&aacute;ctico, en el mundo real de estas etiquetas aparentemente abstractas. <br />
<h3>&iquest;PORQU&Eacute; UN DOCTYPE?</h3>
Para los est&aacute;ndares HTML y XHTML, un DOCTYPE (abreviatura de &ldquo;declaraci&oacute;n de tipo de documento&rdquo;) informa al validador de la versi&oacute;n de (X)HTML que est&aacute;s utilizando, y deber&iacute;a aparecer al principio de cada p&aacute;gina web. Los DOCTYPEs son un componente clave de las p&aacute;ginas veb de conformidad: tu marcado y tus CSS no validar&aacute;n sin ellos.<br /><br />Como fu&eacute; mencionado en art&iacute;culos previos de ALA (y en otros lugares interesantes), los DOCTYPES tambi&eacute;n son esenciales para la apropiada renderizaci&oacute;n y funcionamiento de los documentos web en navegadores de conformidad como Mozilla, IE5/Mac, y IE6/Win.<br /><br />Un DOCTYPE reciente, que incluye una URI completa(una direcci&oacute;n web completa) les dice a estos navegadores que rendericen tu p&aacute;gina en modo conforme con los est&aacute;ndares, tratando tus (X)HTML, CSS, y DOM como esperas que deben ser tratados.<br /><br />Usando un DOCTYPE incompleto u obsoleto&mdash;o ning&uacute;n DOCTYPE&mdash;colocar&aacute; a los mismos navegadores en modo &ldquo;Caprichoso&rdquo;, bajo el que el navegador asume que has escrito a la vieja usanza, marcado inv&aacute;lido y c&oacute;digo para las deprimentes normas de la industria de finales de los 1990.<br /><br />Con esta configuraci&oacute;n, el navegador va a intentar parsear tu p&aacute;gina en modo compatible hacia atr&aacute;s, renderizando tus CSS como deber&iacute;an haber sido vistas en IE4, y revirtiendo a un DOM propietario, espec&iacute;fico de los navegadores. (IE revierte al DOM IE; Mozilla y Netscape 6 revierten a vaya usted a saber.)<br /><br />Claramente, esto no es lo que quer&iacute;as. Pero es frecuentemente lo que tienes, dada la preponderancia de informaci&oacute;n incompleta o incorrecta sobre el DOCTYPE que este art&iacute;culo espera corregir.<br /><br />(Nota: El navegador Opera no se rije por estas reglas; siempre trata de renderizar las p&aacute;ginas en modo conforme con los est&aacute;ndares. &iexcl;Vamos, Opera! En el otro lado, Opera todav&iacute;a no ofrece un soporte s&oacute;lido para el DOM del W3C. Pero est&aacute;n trabajando en ello.) <br />
<h3>&iquest;D&Oacute;NDE HAN IDO A PARAR TODOS LOS DOCTYPES?</h3>
Partiendo de que los DOCTYPES son vitales para el apropiado funcionamiento de los est&aacute;ndares de la web en los navegadores, y dado que el W3C es el principal creador de los est&aacute;ndares de la web, podr&iacute;as esperar que el <a href="http://w3.org/">sitio web</a> del W3C proporcionase un listado de DOCTYPEs apropiados, y podr&iacute;as esperar tambi&eacute;n ser capaza de encontrar esta informaci&oacute;n r&aacute;pida y f&aacute;cilmente en una localizaci&oacute;n &uacute;nica. Pero como que esto est&aacute; escrito, que no puedes. <br /> <br /> W3.org no es <a href="http://www.alistapart.com/">A List Apart</a>, <a href="http://webreference.com/">WebReference</a>, o <a href="http://www.webmonkey.com/">Webmonkey</a>. Su intenci&oacute;n no es ayudar a los dise&ntilde;adores web, desarrolladores, y gente que trabaja con contenidos similares a avanzar m&aacute;s r&aacute;pido en las &uacute;ltimas pr&aacute;cticas y recomendaciones tecnol&oacute;gicas. Ese no es su trabajo. <br /> <br /> W3C publica una serie de <a href="http://www.w3.org/2002/03/tutorials.html">tutoriales</a>, que la mayor&iacute;a de dise&ntilde;adores web ignoran. Sin embargo, el sitio web del W3C aloja principalmente una colecci&oacute;n de propuestas, borradores, y Recomendaciones, escritas por especialistas para especialistas. Y cuando digo especialistas, no quiero decir profesionales web ordinarios, como t&uacute; y como yo. Quiero decir especialistas que hacen que el resto de nosotros la Abuela el primer d&iacute;a que Ella Tuvo un Mail.&trade; <br /> <br /> Puedes buscar DOCTYPEs todo el d&iacute;a en w3.org sin encontrar una p&aacute;gina que ofrezca un listado completo de todos ellos. Y cuando consigues cazar un DOCTYPE (generalmente en relaci&oacute;n con una Recomendaci&oacute;n o Borrador de Trabajo), frecuentemente se trata de uno que no funciona en tu sitio web. <br /> <br /> Dispersos por el sitio web del W3C hay DOCTYPEs con URIs perdidas, y DOCTYPEs con URIs relativas que apuntan a documentos en el propio sitio web del W3C. Una vez que son desplazados del sitio del W3C y utilizados en tus propias p&aacute;ginas web, dichas URIs apuntan a documentos no existentes, haciendo por tanto que sean en vano tus mayores esfuerzos y que fallen los navegadores. <br /> <br /> Por ejemplo, mucho sitios muestran estos DOCTYPEs, copiados y pegados directamente de w3.org:<br />
<pre class="code"> <br /><br /></pre>
Si te fijas en la &uacute;ltima parte del DOCTYPE (&ldquo;DTD/xhtml1-strict.dtd&rdquo;), podr&aacute;s ver que es un link relativo a un documento en el sitio del W3C. Partiendo de que este documento est&aacute; en el sitio web del W3C pero no en el tuyo, la URI carece de utilidad para el navegador. <br /> <br /> El DOCTYPE que te gustar&iacute;a utilizar es:<br /> Debes observar que este &uacute;ltimo DOCTYPE incluye una URI completa al final de la etiqueta. Y como la etiqueta proporciona una localizaci&oacute;n v&aacute;lida en la web, el navegador sabe d&oacute;nde encontrarla, y renderizar&aacute; tu documento en modo conforme con los est&aacute;ndares.<br />
<h3>DOCTYPES QUE FUNCIONAN</h3>
Entonces, &iquest;qu&eacute; DOCTYPEs deber&iacute;amos utilizar? Me alegro de que lo preguntes. Los siguientes DOCTYPEs completos son los &uacute;nicos que necesitamos: <br />
<h4>HTML 4.01 Strict, Transitional, Frameset</h4>
<pre class="code">
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"&gt;
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"&gt;
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd"&gt;
</pre>
<h4>XHTML 1.0 Strict, Transitional, Frameset</h4>
<pre class="code">
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"&gt;
</pre>
<h4>XHTML 1.1 DTD</h4>
<pre class="code">
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"&gt;
</pre>
<h3>SIGUIENTES PASOS</h3>
&iquest;C&oacute;mo puedes colaborar a la mejora del soporte de los est&aacute;ndares en la web? Adem&aacute;s de agregar a favoriots esta p&aacute;gina (y copiar y pegar estos DOCTYPEs para tu propio uso), si tu editor web inserta DOCTYPEs, deber&iacute;as echarles un vistazo y compararlos con los listados arriba. <br /> <br /> Demasiados fabricantes de software bien-intencionados han copiado y pegado DOCTYPEs incompletos del W3C en su software. Resultado: cuando usas la funcionalidad de estos programas de insertar DOCTYPEs en tus p&aacute;ginas, los navegadores se ponen en modo Caprichoso, deshaciendo todo tu laborioso trabajo. <br /> <br /> Merece la pena contactar con la gente que hace tu paquete de autor favorito, mostr&aacute;ndoles los DOCTYPEs apropiados, y sugerirles cort&eacute;smente que tengan en cuenta este aspecto en la siguiente actualizaci&oacute;n. (En algunos casos, tambi&eacute;n ser&aacute;s capaz de <a href="http://www.alistapart.com/articles/dreamweaver/">modificar tu editor</a> por t&iacute; mismo.) <br /><br />Tenemos todas las razones para creer que el sitio del W3C lanzar&aacute; pronto una lista de DOCTYPES acertados, utilizables, y otra informaci&oacute;n esencial en una localizaci&oacute;n f&aacute;cil de encontrar. De hecho, Karl Dubost, Conformance Manager del equipo del W3C <a href="http://www.w3.org/QA/">Quality Assurance</a>, contribuy&oacute; a la informaci&oacute;n de este peque&ntilde;o art&iacute;culo. <br /> <br /> Del mismo modo, el relanzamiento de <a href="http://www.webstandards.org/">The Web Standards Project</a> proporciona en sus p&aacute;ginas <a href="http://www.webstandards.org/learn/templates/">esta informaci&oacute;n</a>.<br />]]></content:encoded>
			<wfw:commentRss>http://www.imaginanet.com/feeds.htm?blog=3</wfw:commentRss>
			<slash:comments>2</slash:comments>
			<feedburner:origLink>http://www.imaginanet.com/blog/arreglando-tu-pagina-web-con-el-doctype-correcto.html</feedburner:origLink>
		</item>
		</channel>
</rss>
