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

<channel>
	<title>Chuso! &#187; chusete</title>
	<atom:link href="http://chusete.es/author/admin/feed/" rel="self" type="application/rss+xml" />
	<link>http://chusete.es</link>
	<description>A la tercera va la vencida</description>
	<lastBuildDate>Tue, 13 Mar 2012 16:06:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Colores</title>
		<link>http://chusete.es/2012/03/09/colores/</link>
		<comments>http://chusete.es/2012/03/09/colores/#comments</comments>
		<pubDate>Fri, 09 Mar 2012 02:29:57 +0000</pubDate>
		<dc:creator>chusete</dc:creator>
				<category><![CDATA[curiosidades]]></category>
		<category><![CDATA[color]]></category>

		<guid isPermaLink="false">http://chusete.es/?p=1343</guid>
		<description><![CDATA[En este post no pretendo descubrir nada a nadie. De hecho, no voy a hablar de nada relacionado con los asuntos que suelo tratar en este blog. Voy a hablar de colores. No, no me he convertido en mujer; sigo dividiendo el mundo en seis colores&#8230; siete, como mucho (solo bromeo ) Disclaimer: Lo que a [...]]]></description>
			<content:encoded><![CDATA[<p>En este post no pretendo descubrir nada a nadie. De hecho, no voy a hablar de nada relacionado con los asuntos que suelo tratar en este blog. Voy a hablar de colores. No, no me he convertido en mujer; sigo dividiendo el mundo en seis colores&#8230; siete, como mucho (solo bromeo <img src='http://chusete.es/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> )<a href="http://chusete.es/wp-content/uploads/2012/03/COLORES.jpg"><img class="aligncenter size-medium wp-image-1344" title="COLORES" src="http://chusete.es/wp-content/uploads/2012/03/COLORES-300x300.jpg" alt="" width="300" height="300" /></a></p>
<p><em><strong>Disclaimer</strong>: Lo que a continuación voy a contar se corresponde con cómo me explicaron a mí las cosas en el colegio y en el instituto. Seguramente tu experiencia haya sido diferente.</em></p>
<p>Ya desde pequeños, una de las primeras cosas que aprendemos es a diferenciar colores. Después, cuando empezamos a colorear, descubrimos que mezclando el lapicero azul con el lapicero amarillo obtenemos verde. ¿Qué clase de brujería es esa?</p>
<div id="attachment_1345" class="wp-caption aligncenter" style="width: 239px"><a href="http://www.cuantocabron.com/inglip/cuando-estabas-en-la-guarderia"><img class="size-medium wp-image-1345" title="CC_1104012_inglip_cuando_estabas_en_la_guarderia" src="http://chusete.es/wp-content/uploads/2012/03/CC_1104012_inglip_cuando_estabas_en_la_guarderia-229x300.jpg" alt="" width="229" height="300" /></a><p class="wp-caption-text">Fuente: cuantocabron.com</p></div>
<p>Acabábamos de aprender que mezclando unos colores obtenemos otros. ¡Aquello era todo un mundo de posibilidades! Estabas deseando que se te acabara el verde para tener la oportunidad de sentirte todo un artista creando tu propio verde a partir del amarillo y el azul.</p>
<p>Unos años después aprendíamos que existen unos colores primarios, el rojo, el amarillo y el azul, a partir de los cuales podíamos crear todos los demás. «¿Y el blanco?», se preguntaba el alumno listillo; «El blanco es la mezcla de todos», nos contestó el profesor, más listillo todavía. ¡Por las barbas de Papá Noël! ¡Mezclando esos tres colores yo siempre obtenía un marrón oscuro con reminiscencias escatológicas! En fin, si lo decía el profesor sería porque es verdad. Lamentablemente, con el tiempo descubrí que el modelo de colores Rojo-Amarillo-Azul es erróneo, y que la mezcla de todos da el blanco solamente en la síntesis aditiva de colores (como veremos más adelante).</p>
<div id="attachment_1346" class="wp-caption aligncenter" style="width: 230px"><a href="http://es.wikipedia.org/wiki/Modelo_de_color_RYB"><img class="size-full wp-image-1346" title="Archivo:Color_mixture" src="http://chusete.es/wp-content/uploads/2012/03/ArchivoColor_mixture.png" alt="" width="220" height="191" /></a><p class="wp-caption-text">Fuente: Wikipedia</p></div>
<p>Un ejercicio típico en plástica consistía en crear el círculo cromático, que trataba de dibujar un círculo que iba recorriendo todos los colores de manera escalonada. Todo encajaba a la perfección.</p>
<div id="attachment_1348" class="wp-caption aligncenter" style="width: 310px"><a href="http://es.wikipedia.org/wiki/C%C3%ADrculo_crom%C3%A1tico"><img class="size-medium wp-image-1348" title="Colouring_pencils" src="http://chusete.es/wp-content/uploads/2012/03/Colouring_pencils-300x199.jpg" alt="" width="300" height="199" /></a><p class="wp-caption-text">Fuente: Wikipedia</p></div>
<p>Ya con unos 12 años, en clases de biología, nos enseñaron que percibimos las imágenes gracias a que en la retina de los ojos tenemos unas células fotoreceptoras, llamadas <a href="http://es.wikipedia.org/wiki/Cono_(c%C3%A9lula)">conos</a>, cuya función es cuantificar el tipo de luz (color) que le llegaba. Además, existían otras células, llamadas <a href="http://es.wikipedia.org/wiki/Bast%C3%B3n_(c%C3%A9lula)">bastones</a>, que recibían imágenes en blanco y negro en condiciones de poca iluminación.</p>
<p>Finalmente, en el instituto, aquellos que éramos de ciencias, aprendimos que la luz es una onda electromagnética formada de unas partículas llamadas fotones. Y que, como todas las ondas, tiene &#8220;picos&#8221;; «imaginad ondas en el agua» nos decían. Cuanto más cerca estuvieran entre sí los picos de cada <em>ola</em>, menor era la longitud de onda. Y nuestros ojos solo perciben un tramo de todas las longitudes de ondas posibles: el <a href="http://es.wikipedia.org/wiki/Espectro_visible">espectro de luz visible</a>. Cada uno de esos puntos de luz visible correspondía a un color. Y fuera del tramo de la luz visible se encontraban las ondas de radio, las ondas Gamma, los rayos X, la luz ultravioleta, los infrarrojos, etc. ¡Guau! ¡Existen muchos más colores que nosotros no podemos ver!</p>
<div id="attachment_1347" class="wp-caption aligncenter" style="width: 310px"><a href="http://es.wikipedia.org/wiki/Espectro_visible"><img class="size-medium wp-image-1347" title="File:Electromagnetic_spectrum-es" src="http://chusete.es/wp-content/uploads/2012/03/FileElectromagnetic_spectrum-es-300x92.png" alt="" width="300" height="92" /></a><p class="wp-caption-text">Fuente: Wikipedia</p></div>
<p>Y aquí termina lo que, al menos a mí, me enseñaron sobre los colores. Pero pensando acerca de ellos, me surgían muchas dudas (que con el tiempo he ido despejando):</p>
<ul>
<li>¿Qué era eso de que la mezcla de los colores primarios daba como resultado el blanco?</li>
<li>¿Dónde quedan el blanco y el negro en todo el espectro de colores? ¿Y los grises?</li>
<li>¿Por qué hay tres colores primarios? ¿Y por qué no cuatro?</li>
<li>Si no vemos nada por encima del rojo, ni por debajo del violeta, ¿por qué vemos colores intermedios entre estos en el círculo cromático?</li>
</ul>
<p>Realmente, me habían enseñado todas las variables de la ecuación. El problema es que desconocía la propia ecuación, por lo que no sabía cómo encajar todos los datos con los que ya contaba.</p>
<p>Empecemos por lo básico: por un lado tenemos objetos que <span style="text-decoration: underline;">emiten luz</span>, y por otro objetos que <span style="text-decoration: underline;">reflejan luz</span>. Por ejemplo, el sol, una bombilla, o la pantalla de un ordenador, emiten luz. Por el contrario, una manzana, la hierba, o una pared, reflejan luz. De ahí surgen dos tipos de síntesis de color:</p>
<ol>
<li><strong><a href="http://es.wikipedia.org/wiki/S%C3%ADntesis_aditiva_de_color">Síntesis aditiva de color</a></strong>: corresponde a aquellos colores que tienen su origen directamente en una fuente de iluminación.</li>
<li><strong><a href="http://es.wikipedia.org/wiki/S%C3%ADntesis_sustractiva_de_color">Síntesis sustractiva de color</a></strong>: corresponde a aquellos colores que son reflejados por materiales no luminosos.</li>
</ol>
<p>Según la síntesis aditiva, tenemos tres colores primarios: Rojo, verde y azul. Absolutamente todos los colores que conocemos surgen de la suma de distintas proporciones de estos tres.</p>
<div id="attachment_1352" class="wp-caption aligncenter" style="width: 210px"><a href="http://es.wikipedia.org/wiki/S%C3%ADntesis_aditiva_de_color"><img class="size-full wp-image-1352" title="Archivo:AdditiveColorMixing" src="http://chusete.es/wp-content/uploads/2012/03/ArchivoAdditiveColorMixing.png" alt="" width="200" height="200" /></a><p class="wp-caption-text">Fuente: Wikipedia</p></div>
<p>Los que nos dedicamos a las páginas web lo sabemos muy bien: asignando un valor entre 0% y 100% a cada uno de estos tres colores, obtenemos todos los demás (este es el famoso sistema <a href="http://es.wikipedia.org/wiki/Modelo_de_color_RGB">RGB</a> que se utiliza en diseño gráfico). Por ejemplo:</p>
<ul>
<li>Negro = 0% de rojo + 0% de verde + 0% de azul.</li>
<li>Amarillo = 100% de rojo + 100% de verde + 0% de azul.</li>
<li>Blanco = 100% de rojo + 100% de verde + 100% de azul.</li>
<li>Gris = 50% de rojo + 50% de verde + 50% de azul.</li>
</ul>
<p>Es decir, combinándolos en proporciones iguales obtenemos colores de la escala de grises. La ausencia de todos ellos nos da negro. Y la suma de todos ellos, blanco. ¿Pero esto es realmente así? ¿O se trata de un artificio teórico creado por algún científico? Con colores que surgen de fuentes de iluminación sí es así. Por ejemplo, la pantalla de tu ordenador está formada por una rejilla de píxels que, todos juntos, crean una imagen. Cada píxel está formado por tres señales distintas: una roja, otra verde y otra azul:</p>
<div id="attachment_1349" class="wp-caption aligncenter" style="width: 310px"><a href="http://en.wikipedia.org/wiki/Pixel"><img class="aligncenter size-medium wp-image-1349" title="Pixel_geometry_01_Pengo" src="http://chusete.es/wp-content/uploads/2012/03/Pixel_geometry_01_Pengo-300x300.jpg" alt="Fuente: Wikipedia" width="300" height="300" /></a><p class="wp-caption-text">Fuente: Wikipedia</p></div>
<p>Lo creas o no, cuando ves un blanco en la pantalla de tu ordenador es porque los tres colores están totalmente iluminados. El resto de colores posibles se crean modificando la proporción de cada color primario de cada píxel.</p>
<p>En resumen: el blanco <em>no existe</em>, no es un color como tal del espectro: es la suma de todos los colores del espectro visible. Por esa razón existen infinitas combinaciones de ondas de luz que producen este <em>color</em>, que se corresponde con la luz que emite nuestra estrella: el Sol. Con eso respondemos la pregunta pregunta: ¿Por qué dicen que la suma de todos los colores da blanco?</p>
<p>Pero de ahí surge otra: ¿Por qué entonces al mezclar los colores de los lápices obtenemos un color que no es blanco? Para contestar a eso tenemos que volver a síntesis sustractiva.</p>
<div id="attachment_1353" class="wp-caption aligncenter" style="width: 310px"><a href="http://es.wikipedia.org/wiki/S%C3%ADntesis_sustractiva_de_color"><img class="size-full wp-image-1353" title="Archivo:SubtractiveColorMixing" src="http://chusete.es/wp-content/uploads/2012/03/ArchivoSubtractiveColorMixing.png" alt="" width="300" height="300" /></a><p class="wp-caption-text">Fuente: Wikipedia</p></div>
<p>Según la teoría sustractiva, tenemos otros tres colores primarios: Cian, Magenta y Amarillo. Corresponde a colores &#8220;tintes&#8221; (filtros), colores que reflejan luz. Realmente cuando a un objeto (material) le aplicas luz solar (luz blanca) absorve parte de la radiación, y otra parte la repele; la parte reflejada es la que vemos, como si se tratara de un filtro que solo dejara pasar una parte de la luz. Es decir, sustraen parte del color, de ahí su nombre. Por esa razón, si mezclamos cian y amarillo, obtenemos verde (la radiación que ninguno de esos dos colores-tinte absorve).</p>
<p>A partir de estos tres otros colores primarios obtenemos el modelo <a href="http://es.wikipedia.org/wiki/CMY">CMY</a>, muy utilizado en artes gráficas. Identifican los colores-tinta, a diferencia del modelo RGB que identifica los colores de un emisor de luz (como la pantalla de una televisión). CMY corresponde a Cian, Magenta y Yellow.</p>
<p>Al igual que en RGB, la mezcla de los colores primarios CMY nos dan nuevos colores:</p>
<ul>
<li>Negro = 100% de cian + 100% de magenta + 100% de amarillo.</li>
<li>Blanco = 0% de cian + 0% de magenta + 0% de amarillo.</li>
<li>Gris = 50% de cian + 50% de magenta + 50% de amarillo.</li>
<li>Verde = 100% de cian + 0% de magenta + 100% de amarillo.</li>
</ul>
<p>Y con esto ya hemos resuelto otra duda: ¿Qué son el blanco, el negro y los grises? Son colores no espectrales; es decir, colores formados a partir de la combinación de otros.</p>
<p>Como curiosidad: en lugar de CMY se suele utilizar <a href="http://es.wikipedia.org/wiki/CMYK">CMYK</a>, donde la K corresponde al color negro. Esto es así porque al imprimir es muy complicado obtener un negro puro a partir de la mezcla de cian, magenta y amarillo. Por esa razón (entre otras) se utiliza un cuarto tinte negro.</p>
<p>Pero seguimos teniendo dudas: ¿Por qué tres y no dos o cuatro colores primarios? Es decir, los seres humanos distinguimos todos los colores del espectro de luz visible, que son aquellos que se encuentran entre longitudes de onda de 380 a 780 nanómetros. Cada uno de esos colores corresponde a una longitud de onda diferente. ¿Por qué esa <em>arbitraria</em> división en tres colores primarios? Pues bien, los colores primarios no son una propiedad de la luz. Su origen es biológico. Si volvemos a nuestras clases de ciencias, recordaremos que tenemos los conos: células fotoreceptoras ubicadas en la retina del ojo. En la especie humana existen tres tipos de conos, en función de un tipo determinado de sustancias:</p>
<ol>
<li>Si contienen eritropsina, detectarán luz de en torno a 650 nanómetros: luz roja.</li>
<li>Si contienen cloropsina, detectarán luz de en torno a 530 nanómetros: luz verde.</li>
<li>Si contienen cianopsina, detectarán luz de en torno a 430 nanómetros: luz azul.</li>
</ol>
<p>Cuando, desde lo que aparentemente es un mismo punto, nos llegan ondas de luz de estos tres colores, nuestro cerebro lo interpreta como blanco. Fascinante, ¿verdad?</p>
<p>Existen algunas especies animales que, en lugar de tres canales de color, perciben cuatro. A este estado se le llama <a href="http://es.wikipedia.org/wiki/Tetracromatismo">tetracromatismo</a>. Y -no es broma- hay estudios que indican que entre el 3% y el 50% de las mujeres tienen este tipo de visión. Al final su mayor sensibilidad para con los colores va a tener una explicación biológica <img src='http://chusete.es/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Ahora que ya hemos revisado los conceptos de síntesis sustractiva de color y del espectro de luz visible, voy a recordar algo que a muchos de nosotros nos enseñó el mayor divulgador científico del siglo XX. Por supuesto estoy hablando de Carl Sagan, y de su serie documental Cosmos. A propósito de la composición de Venus, nos cuenta lo siguiente (puedes saltarte el texto y ver el vídeo más abajo):</p>
<blockquote><p>La siguiente pista procedía de un trabajo realizado con un prisma de cristal. Se hace pasar un intenso rayo de luz ordinario a través de una estrecha abertura y luego a través del prisma. El resultado es que la luz se extiende formando los colores del arco iris. Este diseño de arco iris se llama spectrum. Piensen en ello: la luz entra en el prisma y lo que sale del prisma es luz coloreada, con muchos colores. ¿De dónde proceden? Debían estar ocultos en la luz ordinaria. La luz ordinaria debe ser una mezcla de muchos colores.</p>
<p>Aquí vemos como el espectro va del violeta, pasando por el azul, el verde, el amarillo y el naranja  hasta el rojo. Al ver estos colores los llamamos el espectro de la luz visible. El Sol emite mucha cantidad de luz visible. El aire es transparente. Así que nuestros ojos evolucionaron para ver con luz visible. Sin embargo hay muchas otras frecuencias de luz que nuestros ojos no pueden detectar. Más allá del violeta, está el ultravioleta. Es igual de real, pero se necesitan instrumentos para detectarlo. Más allá del ultravioleta, están los rayos X, y luego los rayos gamma. Al otro lado de la luz visible, más allá del rojo, está el infrarrojo, que también es real y también es invisible. Más allá del infrarrojo están las ondas de radio.</p>
<p>Bien, toda esa escala de rayos que van desde los gamma hasta las ondas de radio y llegan hasta aquí son simplemente diferentes clases de luz. Solamente difieren en su frecuencia. Todas son útiles en astronomía. Sin embargo, dada la limitación de nuestros ojos, tenemos cierto prejuicio o preferencia o chovinismo hacia esa pequeña banda de arco iris de luz visible. Se puede utilizar un espectro, de una forma simple y elegante, para determinar la composición química de algún planeta o estrella lejanos. Diferentes átomos y moléculas absorben diferentes frecuencias, o colores, de luz. Las frecuencias absorvidas aparecen en forma de líneas negras en el espectro de la luz que recibimos del planeta o de la estrella. Cada sustancia tiene una huella dactilar característica; una forma espectral que la permite ser detectada a una gran distancia. En consecuencia, se han podido determinar los gases de la atmósfera de Venus a una distancia de 60 millones de kilómetros: se ha podido averiguar su composición desde la Tierra. Sigue sorprendiéndome que podamos saber de qué está compuesta una cosa a una distancia tan enorme sin poder tocarla jamás.</p>
<p style="text-align: right;">Carl Sagan.</p>
</blockquote>
<p>A continuación tienes el didáctico vídeo de Carl Sagan. Recomiendo verlo a partir del minuto 1:12.<br />
<iframe src="http://www.youtube.com/embed/19K9I4imWcA" frameborder="0" width="420" height="315"></iframe></p>
<p>Es asombroso. A partir de colores que nuestros ojos no pueden ver, somos capaces averiguar la composición de planetas a millones de kilómetros de nosotros.</p>
<p>Pero volvamos a poner los pies en la tierra. Queda todavía una duda que no ha sido resuelta: si el espectro visible va desde el rojo hasta el violeta, ¿cómo es posible que el círculo cromático sea continuo entre estos dos colores? En teoría no deberíamos poder verlos:</p>
<div id="attachment_1357" class="wp-caption aligncenter" style="width: 210px"><a href="http://es.wikipedia.org/wiki/C%C3%ADrculo_crom%C3%A1tico"><img class="size-full wp-image-1357" title="Colorwheel" src="http://chusete.es/wp-content/uploads/2012/03/Colorwheel.gif" alt="" width="200" height="200" /></a><p class="wp-caption-text">Fuente: Wikipedia</p></div>
<p>&nbsp;</p>
<p>Los tonos púrpuras no se corresponden con ninguna longitud de onda determinada; estos colores, al igual que el blanco, &#8220;no existen&#8221;, sino que son combinaciones de otros. En concreto los púrpuras son la suma de un color rojo y de un color violeta. Y es así como cerramos el círculo, con la conocida como <em><a href="http://en.wikipedia.org/wiki/Line_of_purples">línea de púrpuras</a></em>.</p>
<p>Los púrpuras son conocidos como colores no espectrales. Naturalmente, a este grupo pertenecen también el blanco, el negro, los grises, y todos aquellos colores que contienen algún tono de uno de estos colores no espectrales, como por ejemplo los colores pastel (que no son más que colores espectrales con alta luminosidad, es decir, con blanco).</p>
<p>¿No es maravilloso? El cómo nuestro cuerpo es capaz de detectar ondas de luz, interpretarlas, crear combinaciones de estas de forma continua&#8230; todo ello a partir de tres distintos tipos de fotoreceptores en nuestros ojos.</p>
<p>Espero que hayas disfrutado leyendo este artículo tanto como yo redactándolo. Si tienes alguna duda, me encantará leerla y tratar de darle respuesta. Por supuesto, si conoces más curiosidades sobre el color, o conoces la respuesta a otras cuestiones curiosas o poco conocidas, será un placer leerlas.
<div class="tweetmeme_button" style="float: left; margin-right: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fchusete.es%2F2012%2F03%2F09%2Fcolores%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fchusete.es%2F2012%2F03%2F09%2Fcolores%2F&amp;source=chuso&amp;style=normal&amp;service=bit.ly&amp;service_api=R_86054639b9f90148987197dfdc061697&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
]]></content:encoded>
			<wfw:commentRss>http://chusete.es/2012/03/09/colores/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Sombras y degradados en CSS3</title>
		<link>http://chusete.es/2012/03/08/sombras-y-degradados-en-css3/</link>
		<comments>http://chusete.es/2012/03/08/sombras-y-degradados-en-css3/#comments</comments>
		<pubDate>Thu, 08 Mar 2012 20:51:04 +0000</pubDate>
		<dc:creator>chusete</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[box-shadow]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[linear-gradient]]></category>
		<category><![CDATA[radial-gradient]]></category>
		<category><![CDATA[shadows]]></category>

		<guid isPermaLink="false">http://chusete.es/?p=1283</guid>
		<description><![CDATA[Esta vez no voy a hablar de nada nuevo. Muchos diseñadores y maquetadores web están ya incluyendo estos efectos a sus trabajos. Sin embargo, para mí son nuevos Los he utilizado con anterioridad pero muy brevemente, y sin tener muy claro qué hacían y por qué exactamente. Si quieres ir directo a los ejemplos, los tienes aquí. ¡Al [...]]]></description>
			<content:encoded><![CDATA[<p>Esta vez no voy a hablar de nada nuevo. Muchos diseñadores y maquetadores web están ya incluyendo estos efectos a sus trabajos. Sin embargo, para mí son nuevos <img src='http://chusete.es/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Los he utilizado con anterioridad pero muy brevemente, y sin tener muy claro qué hacían y por qué exactamente. Si quieres ir directo a los ejemplos, los tienes <a href="/demos/shadows_gradient/sample.html">aquí</a>. ¡Al lío!</p>
<p><span id="more-1283"></span></p>
<h2>Sombras</h2>
<p>En CSS todo son cajas; a cada elemento del árbol DOM (salvo a los <em>inline</em>, pero esto no viene a cuento) se le asigna una caja, y mediante CSS definimos su ubicación. Algunos de estos elementos se encuentran sobre otros: imagina un párrafo &lt;p&gt; sobre el elemento &lt;body&gt;. Con CSS3 podríamos hacer que el &lt;p&gt; arroje una sombre sobre &lt;body&gt;. Vamos a ver la <a href="http://www.w3.org/TR/css3-background/#box-shadow">sintaxis de esta propiedad</a> en su notación <a href="http://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_Form">EBNF</a>:</p>
<pre>none | &lt;shadow&gt; [ , &lt;shadow&gt; ]*</pre>
<p>Donde:</p>
<pre>&lt;shadow&gt; = inset? &amp;&amp; [ &lt;length&gt;{2,4} &amp;&amp; &lt;color&gt;? ]</pre>
<p>Traducido viene a dar estas dos opciones:</p>
<ol>
<li>none &#8211; En cuyo caso, no se muestra ninguna sombra.</li>
<li>&lt;shadow&gt; [ , &lt;shadow&gt; ]* &#8211; Significa que podemos tener una o más sombras separadas por comas. Cada sombra contiene:</li>
<ol>
<li>inset &#8211; Es un valor opcional. Si se omite, la sombra se arrojará hacia fuera del elemento. En caso de que se especifique &#8216;inset&#8217;, la sombra será arrojada dentro del elemento.</li>
<li>&lt;length&gt;{2,4} &#8211; Introduciremos 2, 3 o 4 longitudes:</li>
<ol>
<li>La primera longitud (obligatoria) establece el desplazamiento horizontal de la sombra. Los valores positivos hacen que la sombra se arroje hacia la derecha, y los negativos hacia la izquierda.</li>
<li>La segunda longitud (obligatoria) establece el desplazamiento vertical de la sombra. Los valores positivos hacen que la sombra se arroje hacia abajo, y los negativos hacia arriba.</li>
<li>La tercera longitud (opcional) especifica el radio blur. Si se introduce cero, la sombra será &#8220;afilada&#8221;, en caso contrario, contendrá más blur a mayor radio.</li>
<li>La tercera longitud (opcional) establece la difusión de la sombra. Los valores positivos hacen que se expanda, y los negativos que se contraiga.</li>
</ol>
<li>color &#8211; Es el color de la sombra. Este valor es opcional. Si no se ha introducido, se usará el valor de la propiedad &#8216;color&#8217;. <strong>Nota:</strong> No lo soportan todos los navegadores.</li>
</ol>
</ol>
<p>Vamos a ver algunos ejemplos de valores válidos según la notación estándar:</p>
<pre name="code" class="css">box-shadow: none;
box-shadow: 2px 2px;
box-shadow: inset 2px -2px;
box-shadow: 2px 2px black;
box-shadow: 1em -1em 0.5em #CCCCCC;
box-shadow: 1em -1em 0.5em 1em rgba(118, 118, 118, 0.5);
box-shadow: inset 1em 0 0.5em -1em rgb(0,0,0);
box-shadow: 2px 2px #000, inset -3px 3px gray;</pre>
<p>Y ahora, vamos a revisar ejemplos que puedes probar hoy en los navegadores:</p>
<h3>Ejemplo 1</h3>
<p><a href="http://chusete.es/wp-content/uploads/2012/03/1_1.png"><img class="aligncenter size-full wp-image-1307" title="1_1" src="http://chusete.es/wp-content/uploads/2012/03/1_1.png" alt="" width="210" height="113" /></a></p>
<pre name="code" class="css">box-shadow: 5px 5px #000;</pre>
<p>Arroja una sombra negra desplazada 5px a la derecha y 5px hacia abajo. No hemos especificado un blur, por lo que la sombra está afilada</p>
<h3>Ejemplo 2</h3>
<p><a href="http://chusete.es/wp-content/uploads/2012/03/1_2.png"><img class="aligncenter size-full wp-image-1308" title="1_2" src="http://chusete.es/wp-content/uploads/2012/03/1_2.png" alt="" width="211" height="115" /></a></p>
<pre name="code" class="css">box-shadow: 5px 5px 3px black;</pre>
<p>Arroja una sombra negra desplazada 3px a la derecha y 3px hacia abajo, con un desenfoque blur de 3px de radio.</p>
<h3>Ejemplo 3</h3>
<p><a href="http://chusete.es/wp-content/uploads/2012/03/1_3.png"><img class="aligncenter size-full wp-image-1309" title="1_3" src="http://chusete.es/wp-content/uploads/2012/03/1_3.png" alt="" width="207" height="107" /></a></p>
<pre name="code" class="css">box-shadow: inset 2px -2px 5px #000;</pre>
<p>Arroja una sombra interna negra desplazada 2px a la derecha y 2px hacia arriba, con un desenfoque blur de 5px de radio.</p>
<h3>Ejemplo 4</h3>
<p><a href="http://chusete.es/wp-content/uploads/2012/03/1_4.png"><img class="aligncenter size-full wp-image-1310" title="1_4" src="http://chusete.es/wp-content/uploads/2012/03/1_4.png" alt="" width="251" height="152" /></a></p>
<pre name="code" class="css">box-shadow: 0 0 0.5em 1em rgba(118, 0, 200, 0.5);</pre>
<p>Arroja una sombra lila, sin desplazamiento, con 0.5em de radio de blur, y expandida 1em.</p>
<h3>Ejemplo 5</h3>
<p><a href="http://chusete.es/wp-content/uploads/2012/03/1_5.png"><img class="aligncenter size-full wp-image-1311" title="1_5" src="http://chusete.es/wp-content/uploads/2012/03/1_5.png" alt="" width="229" height="108" /></a></p>
<pre name="code" class="css">box-shadow: 2em 0 0.5em -1em rgb(0,0,0);</pre>
<p>Arroja una sombra negra desplazada 2em a la derecha, con un desenfoque blur de 0.5em de radio, y contraída 1em.</p>
<h3>Ejemplo 6</h3>
<p><a href="http://chusete.es/wp-content/uploads/2012/03/1_6.png"><img class="aligncenter size-full wp-image-1312" title="1_6" src="http://chusete.es/wp-content/uploads/2012/03/1_6.png" alt="" width="219" height="120" /></a></p>
<pre name="code" class="css">box-shadow: 2px 2px 5px #000, -3px -3px 5px red;</pre>
<p>Arroja una sombra negra desplazada 2px a la derecha y 2px hacia abajo con un desenfoque blur de 5px. Además, arroja otra sombra roja desplazada 3px a la izquierda, 3px hacia arriba, y un desenfoque blur de 5px.</p>
<h3>Ejemplo 7</h3>
<p><a href="http://chusete.es/wp-content/uploads/2012/03/1_7.png"><img class="aligncenter size-full wp-image-1313" title="1_7" src="http://chusete.es/wp-content/uploads/2012/03/1_7.png" alt="" width="216" height="114" /></a></p>
<pre name="code" class="css">box-shadow: 5px 5px 5px gold;
border-radius: 15px;</pre>
<p>Arroja una sombra dorada desplazada 5px a la derecha, 5px hacia abajo y con 5px de radio blur. Además, vemos que la sombra se comporta sigue correctamente el recorrido del borde redondeado.</p>
<h3>Ejemplo 8</h3>
<p><a href="http://chusete.es/wp-content/uploads/2012/03/1_8.png"><img class="aligncenter size-full wp-image-1314" title="1_8" src="http://chusete.es/wp-content/uploads/2012/03/1_8.png" alt="" width="205" height="111" /></a></p>
<pre name="code" class="css">box-shadow: 0 8px 5px -5px red;
border-radius: 15px;</pre>
<p>Arroja una sombra roja desplazada 8px hacia abajo, con 5px de radio blur, y contraída 5px.</p>
<h2>Degradados</h2>
<p>Ya hemos visto las sombras, y como has podido comprobar son muy sencillas. Me gustaría decirte que los degradados son igual o más fáciles, pero lamentablemente no es así: se trata de una herramienta muy potente y versátil, por lo que nos ofrece muchas opciones.</p>
<p>Tenemos dos tipos de degradados: lineares y radiales. Los lineales, como su nombre indican, siguen una trayectoria lineal. Por contra, los radiales siguen una trayectoria circular o elíptica.</p>
<h2>Degradados lineales</h2>
<p>Su uso todavía está sujeto a modificaciones, y cada navegador lo implementa precedido de su propio prefijo y sin cumplir necesariamente la notación estándar:</p>
<ul>
<li>-moz-linear-gradient() para Firefox.</li>
<li>-webkit-linear-gradient() para Safari y Google Chrome.</li>
<li>-o-linear-gradient() para Opera</li>
<li>-ms-linear-gradient() para Internet Explorer 10.</li>
</ul>
<p>Esta es su <a href="http://dev.w3.org/csswg/css3-images/#linear-gradients">notación</a> <strong>estándar</strong>:</p>
<pre>&lt;linear-gradient&gt; = linear-gradient(
    [ [ &lt;angle&gt; | to &lt;side-or-corner&gt; ] ,]?
    &lt;color-stop&gt;[, &lt;color-stop&gt;]+
)

&lt;side-or-corner&gt; = [left | right] || [top | bottom]</pre>
<p>Que significa esto:</p>
<ol>
<li>Contiene un ángulo opcional especificado en &#8216;deg&#8217;. Por ejemplo, 90deg. <strong>Nota:</strong> No está todavía soportado por todos los navegadores.</li>
<li>Un punto de origen opcional precedido por &#8220;to&#8221;, que podría ser left, right, top, bottom, left top, left bottom, right top o right-bottom. Por defecto la trayectoria se traza hacia el lado o vértice opuesto al especificado. <strong>Nota:</strong> los navegadores que implementan esta propiedad solo funcionan si no se precede por &#8220;to&#8221;.</li>
<li>Dos o más colores, donde cada uno de ellos indica:</li>
<ol>
<li>El código del color, por ejemplo #FF00FF.</li>
<li>La posición del color. Por ejemplo, 0%, 30px, 100%. Si no se indica posición, se distribuyen a lo largo del recorrido uniformemente.</li>
</ol>
</ol>
<p>Al igual que con las sombras, vamos a ver algunos valores válidos de acuerdo a la <strong>notación estándar</strong>:</p>
<pre name="code" class="css">background-image: linear-gradient(90deg, yellow, blue);
background-image: linear-gradient(to bottom, red, white);
background-image: linear-gradient(to bottom left, red, black);
background-image: linear-gradient(0deg, #FF0000 10%, #000);
background-image: linear-gradient(to top, red 0%, rgb(129, 5, 205) 50%, #CCC 100%);</pre>
<p>Y ahora, algunos ejemplos reales:</p>
<h3>Ejemplo 1</h3>
<p><a href="http://chusete.es/wp-content/uploads/2012/03/2_1.png"><img class="aligncenter size-full wp-image-1315" title="2_1" src="http://chusete.es/wp-content/uploads/2012/03/2_1.png" alt="" width="208" height="117" /></a></p>
<pre name="code" class="css">background-image: -webkit-linear-gradient(top, black, white);
background-image: -moz-linear-gradient(top, black, white);
background-image: -ms-linear-gradient(top, black, white);
background-image: -o-linear-gradient(top, black, white);</pre>
<p>Degradado, de arriba a abajo, comenzando en negro y finalizando en blanco.</p>
<h3>Ejemplo 2</h3>
<p><a href="http://chusete.es/wp-content/uploads/2012/03/2_2.png"><img class="aligncenter size-full wp-image-1316" title="2_2" src="http://chusete.es/wp-content/uploads/2012/03/2_2.png" alt="" width="208" height="108" /></a></p>
<pre name="code" class="css">background-image: -webkit-linear-gradient(top left, black, white);
background-image: -moz-linear-gradient(top left, black, white);
background-image: -ms-linear-gradient(top left, black, white);
background-image: -o-linear-gradient(top left, black, white);</pre>
<p>Desgradado, de la esquina superior izquierda a la esquina inferior derecha, comenzando en negro y finalizando en blanco.</p>
<h3>Ejemplo 3</h3>
<p><a href="http://chusete.es/wp-content/uploads/2012/03/2_3.png"><img class="aligncenter size-full wp-image-1317" title="2_3" src="http://chusete.es/wp-content/uploads/2012/03/2_3.png" alt="" width="206" height="105" /></a></p>
<pre name="code" class="css">background-image: -webkit-linear-gradient(bottom, red, white, black);
background-image: -moz-linear-gradient(bottom, red, white, black);
background-image: -ms-linear-gradient(bottom, red, white, black);
background-image: -o-linear-gradient(bottom, red, white, black);</pre>
<p>Degradado de abajo hacia arriba, comenzando en rojo, después en blanco, y finalmente en negro.</p>
<h3>Ejemplo 4</h3>
<p><a href="http://chusete.es/wp-content/uploads/2012/03/2_4.png"><img class="aligncenter size-full wp-image-1318" title="2_4" src="http://chusete.es/wp-content/uploads/2012/03/2_4.png" alt="" width="204" height="105" /></a></p>
<pre name="code" class="css">background-image: -webkit-linear-gradient(top, red 70%, black);
background-image: -moz-linear-gradient(top, red 70%, black);
background-image: -ms-linear-gradient(top, red 70%, black);
background-image: -o-linear-gradient(top, red 70%, black);</pre>
<p>Degradado de arriba hacia abajo, de rojo hasta el 70% del recorrido y, desde ahí, hacia negro.</p>
<h3>Ejemplo 5</h3>
<p><a href="http://chusete.es/wp-content/uploads/2012/03/2_5.png"><img class="aligncenter size-full wp-image-1319" title="2_5" src="http://chusete.es/wp-content/uploads/2012/03/2_5.png" alt="" width="205" height="106" /></a></p>
<pre name="code" class="css">background-image: -webkit-linear-gradient(top, red 50%, black 80%, yellow 100%);
background-image: -moz-linear-gradient(top, red 50%, black 80%, yellow 100%);
background-image: -ms-linear-gradient(top, red 50%, black 80%, yellow 100%);
background-image: -o-linear-gradient(top, red 50%, black 80%, yellow 100%);</pre>
<p>Degradado de arriba hacia abajo, de rojo hasta el 50%, negro en el 80% del recorrido, y finalmente a amarillo.</p>
<h3>Ejemplo 6</h3>
<p><a href="http://chusete.es/wp-content/uploads/2012/03/2_6.png"><img class="aligncenter size-full wp-image-1320" title="2_6" src="http://chusete.es/wp-content/uploads/2012/03/2_6.png" alt="" width="205" height="106" /></a></p>
<pre name="code" class="css">background-image: -webkit-linear-gradient(top, red 50%, black 80%, yellow 100%);
background-image: -moz-linear-gradient(top, red 50%, black 80%, yellow 100%);
background-image: -ms-linear-gradient(top, red 50%, black 80%, yellow 100%);
background-image: -o-linear-gradient(top, red 50%, black 80%, yellow 100%);
background-size: 100% 50px;</pre>
<p>Igual que el ejemplo 5, pero estableciendo un tamaño de imagen de fondo de 50px de alto, con lo que el degradado se repite.</p>
<h3>Ejemplo 7</h3>
<p><a href="http://chusete.es/wp-content/uploads/2012/03/2_7.png"><img class="aligncenter size-full wp-image-1321" title="2_7" src="http://chusete.es/wp-content/uploads/2012/03/2_7.png" alt="" width="205" height="102" /></a></p>
<pre name="code" class="css">background-image: -webkit-linear-gradient(top, red 50%, black 80%, yellow 100%);
background-image: -moz-linear-gradient(top, red 50%, black 80%, yellow 100%);
background-image: -ms-linear-gradient(top, red 50%, black 80%, yellow 100%);
background-image: -o-linear-gradient(top, red 50%, black 80%, yellow 100%);
border-radius: 15px;</pre>
<p>Igual que el ejemplo 5, pero con bordes redondeados.</p>
<h2>Degradados radiales</h2>
<p>Al igual que con los degradados lineales, su uso todavía está sujeto a modificaciones, y cada navegador lo implementa precedido de su propio prefijo y sin cumplir necesariamente la notación estándar:</p>
<ul>
<li>-moz-radial-gradient() para Firefox.</li>
<li>-webkit-radial-gradient() para Safari y Google Chrome.</li>
<li>-o-radial-gradient() para Opera</li>
<li>-ms-radial-gradient() para Internet Explorer 10.</li>
</ul>
<p>Esta es su <a href="http://dev.w3.org/csswg/css3-images/#radial-gradients">notación</a> estándar:</p>
<pre>&lt;radial-gradient&gt; = radial-gradient(
    [ [ &lt;shape&gt; || &lt;size&gt; ] [ at &lt;position&gt; ]? , |
        at &lt;position&gt;,
    ]?
    &lt;color-stop&gt; [ , &lt;color-stop&gt; ]+
)</pre>
<p>Que significa esto:</p>
<ul>
<li>shape &#8211; Opcional. Forma del degradado, que puede ser o bien &#8216;circle&#8217; o bien &#8216;ellipse&#8217;.</li>
<li>size &#8211; Opcional. Tamaño. Puede ser:</li>
<ul>
<li>Un único valor absoluto, indicando un círculo. <strong>Nota</strong>: No soportado por los principales navegadores.</li>
<li>Dos valores absolutos o relativos, indicando una elipse. <strong>Nota</strong>: No soportado por los principales navegadores.</li>
<li><em>closest-side</em> &#8211; El degradado se expande hasta que el último color alcanza el lado más cercano del punto de origen. <strong>Nota</strong>: No soportado por los principales navegadores.</li>
<li><em>farthest-side</em> &#8211; El degradado se expande hasta que el último color alcanza el lado más lejano del punto de origen.</li>
<li><em>closest-corner</em> &#8211; El degradado se expande hasta que el último color alcanza la esquina más cerca al punto de origen. <strong>Nota</strong>: No soportado por los principales navegadores.</li>
<li><em>farthest-corner</em> &#8211; El degradado se expande hasta que el último color alcanza la esquina más lejana al punto de origen.</li>
</ul>
<li>position &#8211; Opcional. Posición de origen, precedida por &#8220;at&#8221;. Por omisión, &#8216;center&#8217;. Se especifica la posición horizontal (left, center, right, valor absoluto, o relativo) y vertical (top, center, bottom, valor absoluto, o relativo). <strong>Nota</strong>: Los navegadores que implementan esta propiedad solamente funcionan si no se precede por &#8220;at&#8221;.</li>
<li>Dos o más colores, separados por comas, y opcionalmente acompañados de una posición (por ejemplo, 50% o 3em). Si no se introduce una posición, se distribuyen uniformemente.</li>
</ul>
<p>Algunos ejemplos válidos según la notación estándar:</p>
<pre name="code" class="css">background-image: radial-gradient(circle, black, white);
background-image: radial-gradient(circle, black 50%, white 100%);
background-image: radial-gradient(ellipse, black, white);
background-image: radial-gradient(circle at top left, black, white);
background-image: radial-gradient(circle at 50px 100px, black, white);
background-image: radial-gradient(50px at bottom left, black, white);
background-image: radial-gradient(closest-side at top, black, white);
background-image: radial-gradient(farthest-corner, black, white);
background-image: radial-gradient(circle, black, white, red);</pre>
<p>Sin embargo estos ejemplos no funcionan en los navegadores, pues como hemos visto su notación es ligeramente diferente. Vamos a ver algunos ejemplos que podemos usar hoy:</p>
<h3>Ejemplo 1</h3>
<p><a href="http://chusete.es/wp-content/uploads/2012/03/3_1.png"><img class="aligncenter size-full wp-image-1322" title="3_1" src="http://chusete.es/wp-content/uploads/2012/03/3_1.png" alt="" width="204" height="203" /></a></p>
<pre name="code" class="css">background-image: -webkit-radial-gradient(red, black);
background-image: -moz-radial-gradient(red, black);
background-image: -ms-radial-gradient(red, black);
background-image: -o-radial-gradient(red, black);</pre>
<p>Degradado radial por defecto, de rojo a negro. Como vemos, comienza ubicado en el centro, se distribuye de forma circular, y se expande hasta que el negro alcanza las esquinas.</p>
<h3>Ejemplo 2</h3>
<p><a href="http://chusete.es/wp-content/uploads/2012/03/3_2.png"><img class="aligncenter size-full wp-image-1323" title="3_2" src="http://chusete.es/wp-content/uploads/2012/03/3_2.png" alt="" width="204" height="204" /></a></p>
<pre name="code" class="css">background-image: -webkit-radial-gradient(top center, red, black);
background-image: -moz-radial-gradient(top center, red, black);
background-image: -ms-radial-gradient(top center, red, black);
background-image: -o-radial-gradient(top center, red, black);</pre>
<p>Degradado radial comenzando en el centro superior (top center), de rojo a negro. De nuevo, se expande hasta que el color final (negro) alcanza alguna de las esquinas, adquiriendo por tanto una distribución elíptica.</p>
<h3>Ejemplo 3</h3>
<p><a href="http://chusete.es/wp-content/uploads/2012/03/3_3.png"><img class="aligncenter size-full wp-image-1324" title="3_3" src="http://chusete.es/wp-content/uploads/2012/03/3_3.png" alt="" width="204" height="204" /></a></p>
<pre name="code" class="css">background-image: -webkit-radial-gradient(top center, circle, red, black);
background-image: -moz-radial-gradient(top center, circle, red, black);
background-image: -ms-radial-gradient(top center, circle, red, black);
background-image: -o-radial-gradient(top center, circle, red, black);</pre>
<p>Degradado radial, de rojo a negro, comenzando en el centro superior (top center). En este caso hemos especificado que su distribución sea circular.</p>
<h3>Ejemplo 4</h3>
<p><a href="http://chusete.es/wp-content/uploads/2012/03/3_4.png"><img class="aligncenter size-full wp-image-1325" title="3_4" src="http://chusete.es/wp-content/uploads/2012/03/3_4.png" alt="" width="203" height="200" /></a></p>
<pre name="code" class="css">background-image: -webkit-radial-gradient(top left, red, black);
background-image: -moz-radial-gradient(top left, red, black);
background-image: -ms-radial-gradient(top left, red, black);
background-image: -o-radial-gradient(top left, red, black);</pre>
<p>Degradado de rojo a negro comenzando en la esquina superior izquierda. Desde esa posición todos los extremos quedan a la misma distancia, por lo que la distribución se hace de forma circular.</p>
<h3>Ejemplo 5</h3>
<p><a href="http://chusete.es/wp-content/uploads/2012/03/3_5.png"><img class="aligncenter size-full wp-image-1326" title="3_5" src="http://chusete.es/wp-content/uploads/2012/03/3_5.png" alt="" width="201" height="200" /></a></p>
<pre name="code" class="css">background-image: -webkit-radial-gradient(top left, red, black, white);
background-image: -moz-radial-gradient(top left, red, black, white);
background-image: -ms-radial-gradient(top left, red, black, white);
background-image: -o-radial-gradient(top left, red, black, white);</pre>
<p>Degradado radial, de rojo a blanco, pasando por el negro, desde la esquina superior izquierda.</p>
<h3>Ejemplo 6</h3>
<p><a href="http://chusete.es/wp-content/uploads/2012/03/3_6.png"><img class="aligncenter size-full wp-image-1327" title="3_6" src="http://chusete.es/wp-content/uploads/2012/03/3_6.png" alt="" width="199" height="201" /></a></p>
<pre name="code" class="css">background-image: -webkit-radial-gradient(top left, red 10%, black 30%, white);
background-image: -moz-radial-gradient(top left, red 10%, black 30%, white);
background-image: -ms-radial-gradient(top left, red 10%, black 30%, white);
background-image: -o-radial-gradient(top left, red 10%, black 30%, white);</pre>
<p>Degradado radial, de rojo a blanco, pasando por el negro, desde la esquina superior izquierda. El color rojo se prolonga hasta el 10% del recorrido, el negro se alcanza al 30% del recorrido, y el blanco al final (100%, por ser el último). El degradado se expande hasta la esquina más lejana (farthest-corner).</p>
<h3>Ejemplo 7</h3>
<p><a href="http://chusete.es/wp-content/uploads/2012/03/3_7.png"><img class="aligncenter size-full wp-image-1328" title="3_7" src="http://chusete.es/wp-content/uploads/2012/03/3_7.png" alt="" width="200" height="200" /></a></p>
<pre name="code" class="css">background-image: -webkit-radial-gradient(top left, farthest-side, red 10%, black 30%, white);
background-image: -moz-radial-gradient(top left, farthest-side, red 10%, black 30%, white);
background-image: -ms-radial-gradient(top left, farthest-side, red 10%, black 30%, white);
background-image: -o-radial-gradient(top left, farthest-side, red 10%, black 30%, white);</pre>
<p>Ejemplo igual que el anterior, pero en lugar de expandirse hasta la esquina más lejana (farthest-corner) se expande hasta el lateral más lejano (farthest-side).</p>
<h3>Ejemplo 8</h3>
<p><a href="http://chusete.es/wp-content/uploads/2012/03/3_8.png"><img class="aligncenter size-full wp-image-1329" title="3_8" src="http://chusete.es/wp-content/uploads/2012/03/3_8.png" alt="" width="200" height="200" /></a></p>
<pre name="code" class="css">background-image: -webkit-radial-gradient(top center, ellipse farthest-side, black, white);
background-image: -moz-radial-gradient(top center, ellipse farthest-side, black, white);
background-image: -ms-radial-gradient(top center, ellipse farthest-side, black, white);
background-image: -o-radial-gradient(top center, ellipse farthest-side, black, white);</pre>
<p>Degradado radial, de blanco a negro, comenzando en el centro superior (top center), con distribución elíptica expandiéndose hasta el lateral más lejano (farthest-side).</p>
<h3>Ejemplo 9</h3>
<p><a href="http://chusete.es/wp-content/uploads/2012/03/3_9.png"><img class="aligncenter size-full wp-image-1330" title="3_9" src="http://chusete.es/wp-content/uploads/2012/03/3_9.png" alt="" width="200" height="200" /></a></p>
<pre name="code" class="css">background-image: -webkit-radial-gradient(top center, ellipse farthest-corner, black, white);
background-image: -moz-radial-gradient(top center, ellipse farthest-corner, black, white);
background-image: -ms-radial-gradient(top center, ellipse farthest-corner, black, white);
background-image: -o-radial-gradient(top center, ellipse farthest-corner, black, white);</pre>
<p>Degradado radial, de blanco a negro, comenzando en el centro superior (top center), con distribución elíptica expandiéndose hasta la esquina más lejana (farthest-corner).</p>
<h3>Ejemplo 10</h3>
<p><a href="http://chusete.es/wp-content/uploads/2012/03/3_10.png"><img class="aligncenter size-full wp-image-1331" title="3_10" src="http://chusete.es/wp-content/uploads/2012/03/3_10.png" alt="" width="199" height="15" /></a></p>
<pre name="code" class="css">background-image: -webkit-radial-gradient(top center, ellipse farthest-side, black, white);
background-image: -moz-radial-gradient(top center, ellipse farthest-side, black, white);
background-image: -ms-radial-gradient(top center, ellipse farthest-side, black, white);
background-image: -o-radial-gradient(top center, ellipse farthest-side, black, white);</pre>
<p>Igual que el ejemplo anterior, pero en un contenedor de 15px de altura. Vemos que se produce un efecto de &#8220;destello sombra&#8221; que no podíamos obtener mediante box-shadow.</p>
<h3>Ejemplo 11</h3>
<p><a href="http://chusete.es/wp-content/uploads/2012/03/3_11.png"><img class="aligncenter size-full wp-image-1332" title="3_11" src="http://chusete.es/wp-content/uploads/2012/03/3_11.png" alt="" width="202" height="40" /></a></p>
<pre name="code" class="css">background-image:
    -webkit-radial-gradient(top center, ellipse farthest-side, rgba(255,255,255,1), rgba(255, 255, 255, 0) 50%),
    -webkit-radial-gradient(top center, ellipse farthest-side, gray, white);
background-image:
    -moz-radial-gradient(top center, ellipse farthest-side, rgba(255,255,255,1), rgba(255, 255, 255, 0) 50%),
    -moz-radial-gradient(top center, ellipse farthest-side, gray, white);
background-image:
    -ms-radial-gradient(top center, ellipse farthest-side, rgba(255,255,255,1), rgba(255, 255, 255, 0) 50%),
    -ms-radial-gradient(top center, ellipse farthest-side, gray, white);
background-image:
    -o-radial-gradient(top center, ellipse farthest-side, rgba(255,255,255,1), rgba(255, 255, 255, 0) 50%),
    -o-radial-gradient(top center, ellipse farthest-side, gray, white);
background-size: 100% 40%, 100% 100%;
background-repeat: no-repeat;</pre>
<p>En este caso tenemos un degradado radial elíptico, de blanco (rgba(255,255,255,1)) a blanco transparente (rgba(255,255,255,0)) , comenzando en el centro superior, y alcanzando el lateral más lejano. Además, hemos añadido un segundo degradado igual, pero de gris a blanco. A cada fondo le asignamos un tamaño: El primero ocupará todo el ancho y el 40% de la altura. El segundo, todo el ancho y todo el alto disponible. Para evitar que el primer degradado se repita, añadimos &#8220;background-repeat: no-repeat&#8221;. Con este ejemplo, logramos un efecto sombreado muy llamativo. Hemos añadido sobre él un contenedor para que se aprecie el efecto.</p>
<p>¡Y esto es todo por hoy! Espero que te haya sido de utilidad. Por mi parte, me ha venido de maravilla volcar todo esto en el blog como guía para futuras consultas.</p>
<p>Puedes ver todos los ejemplos en vivo <a href="/demos/shadows_gradient/sample.html">aquí</a>.
<div class="tweetmeme_button" style="float: left; margin-right: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fchusete.es%2F2012%2F03%2F08%2Fsombras-y-degradados-en-css3%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fchusete.es%2F2012%2F03%2F08%2Fsombras-y-degradados-en-css3%2F&amp;source=chuso&amp;style=normal&amp;service=bit.ly&amp;service_api=R_86054639b9f90148987197dfdc061697&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
]]></content:encoded>
			<wfw:commentRss>http://chusete.es/2012/03/08/sombras-y-degradados-en-css3/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Tipos de posts personalizados en WordPress</title>
		<link>http://chusete.es/2011/11/14/tipos-de-posts-personalizados-en-wordpress/</link>
		<comments>http://chusete.es/2011/11/14/tipos-de-posts-personalizados-en-wordpress/#comments</comments>
		<pubDate>Mon, 14 Nov 2011 19:49:30 +0000</pubDate>
		<dc:creator>chusete</dc:creator>
				<category><![CDATA[desarrollo]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[custom posts]]></category>
		<category><![CDATA[taxonomies]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://chusete.es/?p=1243</guid>
		<description><![CDATA[WordPress es una maravilla de software. Nacido en 2003, actualmente es el gestor de contenidos más usado (53.9% de cuota de mercado). La clave de su éxito, en mi opinión, radica en su sencillez de uso, en su versatilidad, en ser un proyecto libre, y sobre todo en su comunidad de usuarios, que crean plugins [...]]]></description>
			<content:encoded><![CDATA[<p>WordPress es una maravilla de software. Nacido en 2003, actualmente es el gestor de contenidos más usado (<a href="http://w3techs.com/technologies/overview/content_management/all">53.9% de cuota de mercado</a>). La clave de su éxito, en mi opinión, radica en su sencillez de uso, en su versatilidad, en ser un proyecto libre, y sobre todo en su comunidad de usuarios, que crean plugins para casi cualquier cosa que podamos imaginar.</p>
<p>¿Pero sabías que se pueden crear <a href="http://codex.wordpress.org/Post_Types">tipos de posts</a> personalizados en los que alojar cualquier tipo de dato que se te ocurra?<br />
<span id="more-1243"></span><br />
Me explico: Por defecto WordPress trae cuatro tipos de posts distintos:</p>
<ol>
<li><strong>Entradas</strong> &#8211; Es el tipo predeterminado, para alojar nuevas entradas tipo blog.</li>
<li><strong>Páginas</strong> &#8211; Las páginas permanentes, fuera de la estructura cronológica de los posts.</li>
<li><strong>Adjuntos</strong>- Corresponde a la página que hay disponible para cada fichero adjunto.</li>
<li><strong>Revisiones</strong> &#8211; Una revisión es una versión antigua de otro documento, o un borrador.</li>
<li><strong>Menús</strong> &#8211; Son los menús de navegación creados desde el panel de control de WordPress. Sí, también es un tipo de post. ¿Sorprendido? <img src='http://chusete.es/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
</ol>
<p>Todos ellos los crea WordPress automáticamente. Pero además de esos, nos permite crear otros nuevos que se adapten mejor a nuestras necesidades. La magia la lleva a cabo la función <a href="http://codex.wordpress.org/Function_Reference/register_post_type">register_post_type()</a>.</p>
<p>Vamos a realizar un ejemplo en el que crearemos un catálogo de discos duros. Cada disco duro tendrá una serie de campos:</p>
<ul>
<li>Nombre</li>
<li>Descripción</li>
<li>Fabricante</li>
<li>Precio</li>
<li>Capacidad</li>
<li>Velocidad de rotación</li>
<li>Imagen</li>
</ul>
<h2>Paso 1 &#8211; Dar de alta el nuevo tipo de post</h2>
<p>Lo primero será crear el nuevo tipo de post. Podremos hacerlo de dos formas: o bien mediante código PHP, o bien desde el panel de control de WordPress.</p>
<h3>Método 1 &#8211; Con código</h3>
<p>Añadimos este código al fichero functions.php de nuestra plantilla:</p>
<pre name="code" class="php">    // Registramos un nuevo tipo de post discos duros
    add_action('init', 'register_dd', 1);
    function register_dd() {
        $labels = array(
            'name' =&gt; _x('Discos duros', 'post type general name'),
            'singular_name' =&gt; _x('Disco duro', 'post type singular name'),
            'add_new' =&gt; _x('Añadir nuevo', 'Disco duro'),
            'add_new_item' =&gt; __('Añadir nuevo disco duro'),
            'edit_item' =&gt; __('Editar disco duro'),
            'new_item' =&gt; __('Nuevo disco duro'),
            'view_item' =&gt; __('Ver disco duro'),
            'search_items' =&gt; __('Buscar discos duros'),
            'not_found' =&gt;  __('No se ha encontrado nada'),
            'not_found_in_trash' =&gt; __('No se ha encontrado nada en la papelera'),
        );
        $args = array(
            'labels' =&gt; $labels,
            'public' =&gt; true,
            'hierarchical' =&gt; false,
            'menu_position' =&gt; 5,
            'has_archive' =&gt; true,
            'query_var' =&gt; true
            'supports' =&gt; array('title','editor','thumbnail'),
            'rewrite' =&gt; array('slug' =&gt; 'disco-duro'),
        );

        register_post_type( 'disco-duro', $args );
    }</pre>
<p>Paso a paso, esto es lo que hacemos:</p>
<ol>
<li>Enganchamos la función &#8220;register_dd()&#8221; al evento &#8220;init&#8221;, dándole alta prioridad (cuanto más bajo, más prioritario).</li>
<li>Definimos la función register_dd():</li>
<ol>
<li>Creamos un array $labels con todas las etiquetas que acompañarán al panel de control de este nuevo tipo de post.</li>
<li>Creamos otro array con todas las opciones:</li>
<ol>
<li>labels &#8211; Por un lado, asignamos las etiquetas.</li>
<li>public &#8211; Le damos visibilidad pública.</li>
<li>hierarchical &#8211; No es un tipo de post jerárquico, donde pueda tener un post padre.</li>
<li>menu_position &#8211; Introduciendo 5 hacemos que se muestre bajo el menú de entradas.</li>
<li>has_archive &#8211; Permitimos acceder al archivo (listado) de discos duros.</li>
<li>query_var &#8211; Indicamos que se podrán hacer consultas atacando a este tipo de post.</li>
<li>supports &#8211; Lista de las funcionalidades que hemos decidido que tenga soporte este tipo de post. En concreto, permitos que tenga un título, una descripción con su editor WYSIWYG, y una imagen de miniatura.</li>
<li>rewrite &#8211; Indicamos el nombre base que tendrán las URLs amigables.</li>
</ol>
<li>Finalmente, damos de alta el tipo de post, al que llamamos &#8216;discoduro&#8217;.</li>
</ol>
</ol>
<p>Si ahora accedemos al panel de control, esto es lo que veremos:</p>
<p><a href="http://chusete.es/wp-content/uploads/2011/10/Añadir-nuevo-disco-duro.png"><img class="aligncenter size-medium wp-image-1244" title="Añadir nuevo disco duro" src="http://chusete.es/wp-content/uploads/2011/10/Añadir-nuevo-disco-duro-300x142.png" alt="" width="300" height="142" /></a></p>
<p>¡Ya tenemos nuestro tipo de post creado! Ha sido fácil, ¿verdad? <img src='http://chusete.es/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<h3>Método 2 &#8211; Sin código</h3>
<p>¿Dije que la comunidad de desarrolladores de WordPress es genial? Existe un plugin que permite hacer todo eso, pero <em>a golpe de ratón</em>. Os presento a <a href="http://wordpress.org/extend/plugins/more-types/">More Types</a>. Mediante formularios web podremos crear y ajustar tanto como queramos nuestros tipos de posts personalizados. Instálatelo y ve a Ajustes &gt; More Types:</p>
<p><a href="http://chusete.es/wp-content/uploads/2011/10/Captura-de-pantalla-2011-10-24-a-las-22.08.31.png"><img class="aligncenter size-medium wp-image-1245" title="More Types" src="http://chusete.es/wp-content/uploads/2011/10/Captura-de-pantalla-2011-10-24-a-las-22.08.31-300x198.png" alt="" width="300" height="198" /></a></p>
<p>Como ves, aparecen tanto los tipos por defecto, como los definidos por el usuario. Vamos a crear un nuevo tipo definido por el usuario pulsando sobre &#8220;Add new Post Type&#8221;. Completamos los siguientes campos:</p>
<ul>
<li><strong>Post type name singular</strong>: Disco duro.</li>
<li><strong>Post type name plural</strong>: Discos duros.</li>
<li><strong>Features</strong>: Marcamos &#8216;Título&#8217;, &#8216;Editor&#8217; y &#8216;Miniatura&#8217;.</li>
</ul>
<div>Desplegamos &#8216;Advanced Settings&#8217;:</div>
<div>
<ul>
<li><strong>Has archive: </strong>Yes<strong>.</strong></li>
<li><strong>Menu position</strong>: 5.</li>
<li><strong>Menu name</strong>: Discos duros.</li>
<li><strong>&#8216;Add new&#8217; text</strong>: Añadir nuevo.</li>
<li><strong>&#8216;Add new item&#8217; text</strong>: Añadir nuevo disco duro.</li>
<li><strong>&#8216;Edit item&#8217; text</strong>: Editar disco duro.</li>
<li><strong>&#8216;New item&#8217; text</strong>: Nuevo disco duro.</li>
<li><strong>&#8216;View item&#8217; text</strong>: Ver disco duro.</li>
<li><strong>&#8216;Search item&#8217; text</strong>: Buscar disco duro.</li>
<li><strong>&#8216;Not found&#8217; text</strong>: No se ha encontrado nada.</li>
<li><strong>&#8216;Not found in Trash&#8217; text</strong>: No se ha encontrado nada en la papelera.</li>
</ul>
<p>Pulsamos sobre &#8216;Save&#8217; y ya lo tenemos. El resultado es el mismo que en el método 1:</p>
<p><a href="http://chusete.es/wp-content/uploads/2011/10/Añadir-nuevo-disco-duro-2.png"><img class="aligncenter size-medium wp-image-1247" title="Añadir nuevo disco duro" src="http://chusete.es/wp-content/uploads/2011/10/Añadir-nuevo-disco-duro-2-300x149.png" alt="" width="300" height="149" /></a></p>
<h2>Paso 2 &#8211; Taxonomías</h2>
<p>La Wikipedia define a la <a href="http://es.wikipedia.org/wiki/Taxonom%C3%ADa">taxonomía</a> como la ciencia de la clasificación; es decir, una forma de agrupar <em>cosas</em>. Lo has usado ya mucho: cada vez que creas una categoría en tus artículos o cuando introduces las etiquetas. Tal como ocurría con los tipos de posts, WordPress trae tres taxonomías creadas de forma predeterminada:</p>
<ol>
<li>Categorías &#8211; Las categorías que ya has usado para clasificar tus artículos.</li>
<li>Etiquetas &#8211; Etiquetas (palabras clave) que añades a cada artículo.</li>
<li>Categoría de enlace &#8211; Las categorías con las que clasificas los enlaces en WordPress.</li>
</ol>
<p>¿Qué taxonomías podemos crear para clasificar los discos duros? Pues unas cuantas <img src='http://chusete.es/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Pero en este ejemplo vamos a crear sólo una: fabricante. Y de nuevo, tal como sucedía al crear los tipos de posts, podemos crearlo o bien con código, o bien utilizando plugins de terceros sin código.</p>
<h3>Método 1 &#8211; Con código</h3>
<p>Podemos crearla mediante código utilizando la función <a href="http://codex.wordpress.org/Function_Reference/register_taxonomy">register_taxonomy()</a>:</p>
<pre name="code" class="php">    // Y creamos un nueva taxonomía para el nuevo tipo de post
    add_action('init', 'register_df', 1);
    function register_df() {
        $labels = array(
            'name' =&gt; _x( 'Fabricantes', 'taxonomy general name' ),
            'singular_name' =&gt; _x( 'fabricante', 'taxonomy singular name' ),
            'search_items' =&gt;  __( 'Buscar fabricantes' ),
            'popular_items' =&gt; __( 'Fabricantes' ),
            'all_items' =&gt; __( 'Todos' ),
            'edit_item' =&gt; __( 'Editar fabricante' ),
            'update_item' =&gt; __( 'Actualizar fabricante' ),
            'add_new_item' =&gt; __( 'Añadir nuevo fabricante' ),
            'new_item_name' =&gt; __( 'Nuevo nombre de fabricante' ),
            'separate_items_with_commas' =&gt; __( 'Separar fabricantes con comas' ),
            'add_or_remove_items' =&gt; __( 'Añadir o borrar fabricantes' ),
            'choose_from_most_used' =&gt; __( 'Elegir de entre los fabricantes más populares' )
        );
        $args = array(
            'hierarchical' =&gt; true,
            'public' =&gt; true,
            'labels' =&gt; $labels,
            'show_ui' =&gt; true,
            'rewrite' =&gt; array( 'slug' =&gt; 'fabricantes' ),
            'query_var' =&gt; true,
		);

        register_taxonomy('fabricantes', 'discosduros', $args);
    }</pre>
<p>Viéndolo paso a paso:</p>
<ol>
<li>Atamos la función &#8216;register_df&#8217;()&#8217; al evento &#8216;init&#8217;, de nuevo con alta prioridad.</li>
<li>Definimos la función register_df():</li>
<ol>
<li>Creamos un array $labels con todas las etiquetas que acompañarán al panel de control de este nuevo tipo de taxonomía.</li>
<li>Creamos otro array con todas las opciones:</li>
<ol>
<li>hierarchical &#8211; Es un tipo de taxonomía jerárquica. Por ejemplo, las categorías son jerárquicas, mientras que las etiquetas no lo son.</li>
<li>public &#8211; Le damos visibilidad pública.</li>
<li>labels &#8211; Por un lado, asignamos las etiquetas.</li>
<li>show_ui &#8211; Indicamos que se mostrará la interfaz de usuario en el panel de control para gestionarlas.</li>
<li>rewrite &#8211; Nos permite redefinir la estructura de las URLs dinámicas con las que se accede a cada fabricante.</li>
<li>query_var &#8211; Permite realizar consultas SQL atacando a esta taxonomía.</li>
</ol>
<li>Finalmente, damos de alta el tipo de taxonomía, a la que llamamos &#8216;fabricantes&#8217;, y la vinculamos al tipo de post &#8216;discosduros&#8217;.</li>
</ol>
</ol>
<div>¿Qué cambio ha supuesto esto? En resumen, tenemos dos. Por un lado, nos aparecerá una nueva cajita en la página de añadir/editar disco duro, donde podremos establecer el fabricante:</div>
<div><a href="http://chusete.es/wp-content/uploads/2011/11/Añadir-nuevo-disco-duro-‹-Demo-—-WordPress.png"><img class="aligncenter size-medium wp-image-1252" title="Añadir nuevo disco duro ‹ Demo — WordPress" src="http://chusete.es/wp-content/uploads/2011/11/Añadir-nuevo-disco-duro-‹-Demo-—-WordPress-300x166.png" alt="" width="300" height="166" /></a></div>
<div>Y por otro, tenemos un nuevo apartado en la columna izquierda desde donde podremos gestionar los fabricantes:</div>
<div><a href="http://chusete.es/wp-content/uploads/2011/11/Fabricantes-‹-Demo-—-WordPress.png"><img class="aligncenter size-medium wp-image-1253" title="Fabricantes ‹ Demo — WordPress" src="http://chusete.es/wp-content/uploads/2011/11/Fabricantes-‹-Demo-—-WordPress-300x166.png" alt="" width="300" height="166" /></a></div>
</div>
<div>
<h3>Método 2 &#8211; Sin código</h3>
</div>
<p>Espera, ¿dije que la comunidad de desarrolladores de WordPress es genial? <img src='http://chusete.es/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  También existe un plugin que nos permita crear taxonomías desde el panel de control. En esta ocasión os presento a <a href="http://wordpress.org/extend/plugins/more-taxonomies/">More Taxonomies</a> (ojo, está en estado beta). Mediante formularios web podremos crear y ajustar tanto como queramos nuestros tipos de taxonomías personalizadas. Instálatelo y ve a Ajustes &gt; More Taxonomies:</p>
<p><a href="http://chusete.es/wp-content/uploads/2011/11/More-Taxonomies-‹-Demo-2-—-WordPress.png"><img class="aligncenter size-medium wp-image-1254" title="More Taxonomies ‹ Demo 2 — WordPress" src="http://chusete.es/wp-content/uploads/2011/11/More-Taxonomies-‹-Demo-2-—-WordPress-300x164.png" alt="" width="300" height="164" /></a></p>
<p>Como ves, al pie aparecen tanto las taxonomías por defecto, como las definidos por el usuario. Vamos a crear una nueva taxonomía definida por el usuario pulsando sobre &#8220;Add new Taxonomie&#8221;. Completamos los siguientes campos:</p>
<ul>
<li><strong>Taxonomy name singular</strong>: Disco duro.</li>
<li><strong>Taxonomy name plural</strong>: Discos duros.</li>
<li><strong>Hierarchical</strong>: Yes</li>
<li><strong>Allow permalinks</strong>: Yes</li>
<li><strong>Taxonomy slug</strong>: fabricante</li>
<li><strong>Show tag cloud</strong>: No</li>
<li><strong>Available to</strong>: Discos duro</li>
</ul>
<div>Desplegamos &#8216;Advanced Settings&#8217;:</div>
<div>
<ul>
<li><strong>Allow queries: </strong>Yes.</li>
<li><strong>Query variable</strong>: fabricante.</li>
<li><strong>&#8216;Search&#8217; label text</strong>: Buscar fabricantes.</li>
<li><strong>&#8216;Popular&#8217; label text</strong>: Fabricantes.</li>
<li><strong>&#8216;All&#8217; label text</strong>: Todos.</li>
<li><strong>&#8216;Edit&#8217; label text</strong>: Editar fabricante.</li>
<li><strong>&#8216;Update&#8217; label text</strong>: Actualizar fabricante.</li>
<li><strong>&#8216;Add new&#8217; label text</strong>: Añadir fabricante.</li>
<li><strong>&#8216;Add new name&#8217; label text</strong>: Nuevo nombre de fabricante.</li>
<li><strong>&#8216;Separate with commas&#8217; label text</strong>: Separar fabricantes con comas.</li>
<li><strong>&#8216;Add or remove item&#8217; label</strong>: Añadir o borrar fabricantes.</li>
<li><strong>&#8216;Choose from most used&#8217; label</strong>: Elegir de entre los fabricantes más populares.</li>
</ul>
<div>Pulsamos sobre &#8216;Save&#8217;, y ya tenemos creada nuestra nueva taxonomía. De nuevo, el resultado es equivalente a realizarlo sin código:</div>
</div>
<div><a href="http://chusete.es/wp-content/uploads/2011/11/Fabricantes-‹-Demo-2-—-WordPress.png"><img class="aligncenter size-medium wp-image-1256" title="Fabricantes ‹ Demo 2 — WordPress" src="http://chusete.es/wp-content/uploads/2011/11/Fabricantes-‹-Demo-2-—-WordPress-300x166.png" alt="" width="300" height="166" /></a></div>
<h2>Paso 3 &#8211; Añadir nuevos campos</h2>
<div>Nuestro nuevo tipo de post ya es capaz de alojar 4 de los 7 campos que queríamos para cada disco duro:</div>
<div>
<ol>
<li>Nombre.</li>
<li>Descripción.</li>
<li>Imagen.</li>
<li>Fabricante.</li>
</ol>
<div>Pero nos quedan otros tres:</div>
<div>
<ol>
<li>Precio.</li>
<li>Capacidad.</li>
<li>Velocidad de rotación.</li>
</ol>
<p>Dado que tanto la capacidad como la velocidad de rotación son cifras más o menos redondas que comparten muchos discos duros entre sí, podríamos haber creado una taxonomía para cada uno de ellos, tal como hemos hecho con los fabricantes. Sin embargo, y dado que se trata de un ejemplo didáctico, vamos a utilizar otro método.</p>
<p>Seguramente ya sepas que WordPress permite añadir campos personalizados a cada post (incluso en las entradas normales tipo blog). Puedes conocer mucho más sobre ellos en el apartado &#8216;<a href="http://codex.wordpress.org/Custom_Fields">Custom Fields</a>&#8216; de la documentación de WordPress. Su funcionamiento es muy sencillo: Cuando estés editando un post, activa la vista de los campos personalizados. Pulsa sobre &#8216;Opciones de pantalla&#8217; y activa el checkbox &#8216;Campos personalizados&#8217;. Ahora, al pie del formulario te aparecerá un nuevo apartado para gestionar los campos personalizados:</p>
<p><a href="http://chusete.es/wp-content/uploads/2011/11/Captura-de-pantalla-2011-11-14-a-las-14.28.17.png"><img class="aligncenter size-medium wp-image-1257" title="Captura de pantalla 2011-11-14 a la(s) 14.28.17" src="http://chusete.es/wp-content/uploads/2011/11/Captura-de-pantalla-2011-11-14-a-las-14.28.17-300x95.png" alt="" width="300" height="95" /></a></p>
<p>Su funcionamiento es de tipo clave-valor. Es decir, introduces un nombre, que será el nombre con el que más adelante podrás acceder al campo personalizados, y finalmente escribes el valor que contiene la <em>variable</em>.</p>
<p>Por ejemplo, podríamos crear el campo &#8216;size&#8217;, donde especificar el tamaño de cada disco duro. En ese caso, pondríamos:</p>
<ul>
<li>Nombre: size</li>
<li>Valor: el tamaño, por ejemplo 1TB.</li>
</ul>
<p>Y pulsamos sobre &#8216;Añadir un campo personalizado&#8217;.</p>
<p>Todo esto funciona muy bien, pero ¿y si nos confundimos al escribir el nombre del campo? ¿Y si no lo recordamos? ¿O si se nos olvida introducir un campo? A diferencia de los dos pasos anteriores, esta vez creo que es muy recomendable crear nuestros nuevos tipos de datos mediante plugins. Es decir, de nuevo, ¡la comunidad de WordPress sale al rescate! Si ya os he presentado <strong>More Types</strong> y <strong>More Taxonomies</strong>, ¿sabéis quién queda? Os presento a <a href="http://wordpress.org/extend/plugins/more-fields/">More Fields</a>.</p>
<p>Con More Fields podremos crear campos personalizados de cualquier tipo (radio, checkbox, text, textarea, select, etc.), adjuntos a cualquiera de los tipos de post. En concreto vamos a crear nuestros tres campos (precio, capacidad, velocidad de rotación) a nuestro tipo de post personalizado (discos duros).</p>
<p>Una vez que lo hemos instalado, vamos a Ajustes &gt; More Fields, y creamos un nuevo bloque de campos (caja donde ubicaremos los nuevos campos) llamado &#8216;Características&#8217;, vinculado al tipo de post &#8216;Disco duro&#8217;, y pulsamos sobre &#8216;Save&#8217;:</p>
<p><a href="http://chusete.es/wp-content/uploads/2011/11/Captura-de-pantalla-2011-11-14-a-las-15.21.28.png"><img class="aligncenter size-medium wp-image-1259" title="Captura de pantalla 2011-11-14 a la(s) 15.21.28" src="http://chusete.es/wp-content/uploads/2011/11/Captura-de-pantalla-2011-11-14-a-las-15.21.28-300x128.png" alt="" width="300" height="128" /></a>Ya creado, accedemos a nuestro nuevo bloque y pulsamos sobre &#8216;Add new Field&#8217; para cada uno de los campos.</p>
<h3>Precio</h3>
<p>Introducimos estos valores:</p>
<ul>
<li><strong>Field title</strong> &#8211; Corresponde al título que aparecerá junto al campo: <em>Precio</em>.</li>
<li><strong>Custom field key</strong> &#8211; Nombre que tendrá la clave cuando queramos acceder al campo desde la plantilla: <em>price</em>.</li>
<li><strong>Caption</strong> &#8211; Texto con instrucciones junto al campo: <em>Introduzca el precio en Euros</em>.</li>
<li><strong>Field type</strong> &#8211; Number</li>
</ul>
<div>Y pulsamos sobre &#8216;Save&#8217;.</div>
<h3></h3>
<h3>Capacidad</h3>
<p>Introducimos estos valores:</p>
<ul>
<li><strong>Field title</strong> - <em>Capacidad</em>.</li>
<li><strong>Custom field key</strong> - <em>size</em>.</li>
<li><strong>Caption</strong> - <em>Introduzca la capacidad del disco duro en GigaBytes.</em></li>
<li><strong>Field type</strong> - Number</li>
</ul>
<div>Y pulsamos sobre &#8216;Save&#8217;.</div>
<div>
<h3></h3>
<h3>Velocidad de rotación</h3>
<p>Introducimos estos valores:</p>
<ul>
<li><strong>Field title</strong> - <em>Velocidad de rotación</em>.</li>
<li><strong>Custom field key</strong> - <em>speed</em>.</li>
<li><strong>Caption</strong> - <em>Seleccione la velocidad de rotación en revoluciones por minuto.</em></li>
<li><strong>Field type</strong> - Select.</li>
<li><strong>Values</strong> - 15000, 10000, 7200, 5400, 4800.</li>
</ul>
<p>Y pulsamos sobre &#8216;Save&#8217;.</p>
</div>
<p>¡Y ya tenemos creados los tres campos que nos faltaban! Si ahora accedemos al formulario de añadir o editar disco duro, veremos esto:</p>
<p><a href="http://chusete.es/wp-content/uploads/2011/11/Captura-de-pantalla-2011-11-14-a-las-15.36.43.png"><img class="aligncenter size-medium wp-image-1260" title="Captura de pantalla 2011-11-14 a la(s) 15.36.43" src="http://chusete.es/wp-content/uploads/2011/11/Captura-de-pantalla-2011-11-14-a-las-15.36.43-300x110.png" alt="" width="300" height="110" /></a>Ya tenemos nuestro nuevo tipo de post creado al completo: Podemos crear nuevos discos duros, gestionar sus fabricantes, su imagen destacada, su título y descripción, y añadir las características técnicas del mismo. Mola, ¿verdad? <img src='http://chusete.es/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2>Paso 4 &#8211; Mejorando el panel de discos duros</h2>
<p>Este paso no es estrictramente necesario, pero puede mejorar notablemente la experiencia de uso a la hora de trabajar con nuestros tipos de post personalizados. Vamos a hacer que el panel de control de discos duros sea mucho más amigable. Vamos a pasar de este panel:</p>
<p><a href="http://chusete.es/wp-content/uploads/2011/11/Captura-de-pantalla-2011-11-14-a-las-16.16.45.png"><img class="aligncenter size-medium wp-image-1261" title="Captura de pantalla 2011-11-14 a la(s) 16.16.45" src="http://chusete.es/wp-content/uploads/2011/11/Captura-de-pantalla-2011-11-14-a-las-16.16.45-300x66.png" alt="" width="300" height="66" /></a>a este otro:</p>
<p><a href="http://chusete.es/wp-content/uploads/2011/11/Captura-de-pantalla-2011-11-14-a-las-16.17.33.png"><img class="aligncenter size-medium wp-image-1262" title="Captura de pantalla 2011-11-14 a la(s) 16.17.33" src="http://chusete.es/wp-content/uploads/2011/11/Captura-de-pantalla-2011-11-14-a-las-16.17.33-300x64.png" alt="" width="300" height="64" /></a>mucho más adaptado a nuestras necesidades, con más columnas, todas ellas ordenables, y con nuevos filtros en función del fabricante. Estos códigos están extraídos de la <a href="http://yoast.com/custom-post-type-snippets/">web de Yoast</a>. Simplemente copiamos y pegamos estos bloques de código al funcions.php de nuestra plantilla:</p>
<h3>Añadiendo nuevas columnas</h3>
<pre name="code" class="php">function change_columns( $cols ) {
  $cols = array(
    'cb'            =&gt; '&lt;input type="checkbox" /&gt;',
    'title'         =&gt; __( 'Nombre', 'trans'),
    'manufacturer'  =&gt; __( 'Fabricante',      'trans' ),
    'size'          =&gt; __( 'Capacidad', 'trans' ),
    'price'         =&gt; __( 'Precio', 'trans' ),
  );
  return $cols;
}
add_filter( "manage_disco-duro_posts_columns", "change_columns" );

// Definir contenido de las columnas no estándar
function custom_columns( $column, $post_id ) {
  switch ( $column ) {
    case "manufacturer":
      $manufacturers = get_the_terms($post_id, 'fabricante');
      foreach($manufacturers as $item) {
        echo '&lt;a href="/'.$item-&gt;taxonomy."/".$item-&gt;slug.'"&gt;'.$item-&gt;name."&lt;/a&gt;";
        break;
      }
      break;
    case "size":
      echo get_post_meta( $post_id, 'size', true)." GB";
      break;
    case "price":
      echo get_post_meta( $post_id, 'price', true)." €";
      break;
  }
}
add_action( "manage_disco-duro_posts_custom_column", "custom_columns", 10, 2 );</pre>
<h3>Haciendo las columnas ordenables</h3>
<pre name="code" class="php">function sortable_columns() {
  return array(
    'title' =&gt; 'title',
    'manufacturer'      =&gt; 'manufacturer',
    'size' =&gt; 'size',
    'price'     =&gt; 'price'
  );
}
add_filter( "manage_edit-disco-duro_sortable_columns", "sortable_columns" );</pre>
<h3>Añadir filtros para las taxonomías</h3>
<pre name="code" class="php">function taxonomy_filter_restrict_manage_posts() {
    global $typenow;

    if ( $typenow == 'disco-duro' ) {
    	$filters = get_object_taxonomies( $typenow );

        foreach ( $filters as $tax_slug ) {
            $tax_obj = get_taxonomy( $tax_slug );
            wp_dropdown_categories( array(
                'show_option_all' =&gt; __('Mostrar todos los '.$tax_obj-&gt;label ),
                'taxonomy' 	  =&gt; $tax_slug,
                'name' 		  =&gt; $tax_obj-&gt;name,
                'orderby' 	  =&gt; 'name',
                'selected' 	  =&gt; $_GET[$tax_slug],
                'hierarchical' 	  =&gt; $tax_obj-&gt;hierarchical,
                'show_count' 	  =&gt; false,
                'hide_empty' 	  =&gt; true
            ) );
        }
    }
}
add_action( 'restrict_manage_posts', 'taxonomy_filter_restrict_manage_posts' );

function taxonomy_filter_post_type_request( $query ) {
  global $pagenow, $typenow;

  if ( 'edit.php' == $pagenow ) {
    $filters = get_object_taxonomies( $typenow );
    foreach ( $filters as $tax_slug ) {
      $var = &amp;$query-&gt;query_vars[$tax_slug];
      if ( isset( $var ) ) {
        $term = get_term_by( 'id', $var, $tax_slug );
        $var = $term-&gt;slug;
      }
    }
  }
}
add_filter( 'parse_query', 'taxonomy_filter_post_type_request' );</pre>
<p>¡Y ya tenemos nuestro panel de control personalizado para nuestro tipo de dato personalizado!</p>
<h2>Paso 5 &#8211; Plantillas</h2>
<p>Supongo que estarás familiarizado con el desarrollo de plantillas en WordPress. Por si acaso no lo estás, te recomiendo revisar la <a href="http://codex.wordpress.org/Template_Hierarchy">jerarquía de plantillas</a>, para saber cuáles tenemos que definir. En concreto podríamos definir estas:</p>
<ul>
<li>Lista de discos duros.</li>
<li>Vista de un disco duro.</li>
<li>Lista de fabricantes de discos duros.</li>
<li>Vista de un fabricante de discos duros.</li>
</ul>
<div>¿Cómo sabemos qué ficheros debemos editar o crear? Si revisamos el diagrama de la jerarquía de plantillas de WordPress, lo veremos muy claro:</div>
<h3><img class="alignnone aligncenter" src="http://codex.wordpress.org/images/1/18/Template_Hierarchy.png" alt="" width="100%" /></h3>
<p>Pero antes de nada; vamos a asegurarnos de que ya podemos acceder a las páginas de nuestros discos duros, y al listado. Da de alta un nuevo elemento de tipo disco duro y, una vez guardado, pulsa sobre &#8220;Ver disco duro&#8221;. Te llevará a una URL similar a www.example.com/disco-duro/nombre-del-disco-duro. Si te fijas en el diagrama, verás que se está utilizando el fichero de plantilla single.php. Del mismo modo, para acceder a la lista de discos duros (www.example.com/disco-duro/) se utiliza el fichero por defecto archive.php.</p>
<div class="note">
<h3>¿Errores 404?</h3>
<p>Si te sale un error 404 &#8211; página no encontrada, prueba a ir a Ajustes &gt; Enlaces permanentes &gt; Guardar. Es simplemente para refrescar la configuración de reescritura de URLs.</p>
</div>
<h3><span class="Apple-style-span" style="font-size: 13px; font-weight: normal;">Ahora si, por ejemplo, quisiéramos editar la vista de un disco duro, editaríamos single-disco-duro.php. Un buen punto de partida suele ser copiar y pegar el contenido del fichero single.php para después adaptarlo a las nuevas necesidades. Por ejemplo, así podría quedarte:</span></h3>
<pre name="code" class="php">&lt;?php get_header(); ?&gt;

&lt;?php if ( have_posts() ) while ( have_posts() ) : the_post(); ?&gt;
    &lt;?php $manufacturers = get_the_terms(get_the_ID(), 'fabricante');?&gt;
	&lt;?php $custom = get_post_custom(); ?&gt;
	&lt;h1 class="entry-title"&gt;&lt;?php the_title(); ?&gt;&lt;/h1&gt;
    &lt;?php
    if ( has_post_thumbnail() ) {
      the_post_thumbnail();
    }
    ?&gt;
	&lt;h2&gt;Fabricante: &lt;?php foreach($manufacturers as $item) { echo $item-&gt;name; break; } ?&gt;&lt;/h2&gt;
    &lt;?php the_content(); ?&gt;
    &lt;p&gt;
        Precio: &lt;?php echo $custom['price'][0]; ?&gt;€&lt;br /&gt;
        Capacidad: &lt;?php echo $custom['size'][0]; ?&gt;GB&lt;br /&gt;
        Velocidad: &lt;?php echo $custom['speed'][0]; ?&gt; rpm&lt;br /&gt;
    &lt;/p&gt;
&lt;?php endwhile; // end of the loop. ?&gt;

&lt;?php get_sidebar(); ?&gt;
&lt;?php get_footer(); ?&gt;</pre>
<p>Y procederíamos de igual manera para editar las vistas de categorías o del listado de discos duros (archive-disco-duro.php).</p>
<p>Pero un momento&#8230; Nos hemos saltado la explicación de cómo utilizar en nuestras plantillas los valores de los campos personalizados. En general, para utilizar estos valores, tenemos cuatro funciones disponibles:</p>
<ol>
<li><a href="http://codex.wordpress.org/Function_Reference/get_post_custom">get_post_custom()</a> &#8211; Devuelve un array que, para cada clave (cada campo personalizado) contiene otro array con todos los valores que se le han asignado.</li>
<li><a href="http://codex.wordpress.org/Function_Reference/get_post_custom_values">get_post_custom_values()</a> &#8211; Útil para cuando un campo personalizado tiene más de un valor. Devuelve un array con todos los valores que se le ha asignado.</li>
<li><a href="http://codex.wordpress.org/Function_Reference/get_post_custom_keys">get_post_custom_keys()</a> &#8211; Devuelve un array con los nombres de claves (campos personalizados) que hay en uso en un determinado post.</li>
<li><a href="http://codex.wordpress.org/Function_Reference/get_post_meta">get_post_meta()</a> &#8211; Devuelve el valor de los campos personalizados que tengan el nombre indicado.</li>
</ol>
<p>¡Y esto es todo! Con un poco de suerte, todo esto te será de tanta utilidad como a mí a la hora de desarrollar nuevas páginas en WordPress. Ya no estás limitado a Páginas y a Entradas. Y lo mejor de todo: se puede hacer casi sin tocar una línea de código.</p>
</div>
</div>
<div class="tweetmeme_button" style="float: left; margin-right: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fchusete.es%2F2011%2F11%2F14%2Ftipos-de-posts-personalizados-en-wordpress%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fchusete.es%2F2011%2F11%2F14%2Ftipos-de-posts-personalizados-en-wordpress%2F&amp;source=chuso&amp;style=normal&amp;service=bit.ly&amp;service_api=R_86054639b9f90148987197dfdc061697&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
]]></content:encoded>
			<wfw:commentRss>http://chusete.es/2011/11/14/tipos-de-posts-personalizados-en-wordpress/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mini-receta: Tunel SSH</title>
		<link>http://chusete.es/2011/10/10/mini-receta-tunel-ssh/</link>
		<comments>http://chusete.es/2011/10/10/mini-receta-tunel-ssh/#comments</comments>
		<pubDate>Mon, 10 Oct 2011 09:33:35 +0000</pubDate>
		<dc:creator>chusete</dc:creator>
				<category><![CDATA[sistemas]]></category>
		<category><![CDATA[ssh]]></category>
		<category><![CDATA[túnel ssh]]></category>

		<guid isPermaLink="false">http://chusete.es/?p=1237</guid>
		<description><![CDATA[Un túnel SSH es una técnica que te permite encaminar un determinado tráfico a través de una conexión SSH. Por ejemplo, supón que conectas a un servicio de ficheros remoto mediante FTP. Todo el tráfico entre el cliente y el servidor viajará sin estar cifrado, por lo que estaríamos expuestos a un ataque Man-in-the-middle, en [...]]]></description>
			<content:encoded><![CDATA[<p>Un túnel SSH es una técnica que te permite encaminar un determinado tráfico a través de una conexión SSH. Por ejemplo, supón que conectas a un servicio de ficheros remoto mediante FTP. Todo el tráfico entre el cliente y el servidor viajará sin estar cifrado, por lo que estaríamos expuestos a un <a href="http://es.wikipedia.org/wiki/Ataque_Man-in-the-middle">ataque Man-in-the-middle</a>, en el que un atacante con acceso a nuestra conexión podría interceptar todos los paquetes para su consulta o modificación. Si enrutaramos todo este tráfico mediante un túnel SSH, evitaríamos estos problemas, asegurándonos un tráfico seguro añadiendo la capa SSH. De hecho, es común utilizar <a href="http://en.wikipedia.org/wiki/File_Transfer_Protocol#FTP_over_SSH_.28not_SFTP.29">FTP sobre SSH</a> (no confundir con <a href="http://es.wikipedia.org/wiki/Sftp">SFTP</a>, que es un protocolo distinto).</p>
<p>Sin embargo, esta técnica tiene más utilidades, que es la que a mí personalmente más práctica me resulta. Supón que te dan acceso a un servicio remoto que sólo autoriza para conectar a una determinada IP. Si quisieras conectar a ese servicio desde una conexión de banda ancha convencional o desde la red 3G, tendrías un problema, ya que, salvo que lo hayas contratado explícitamente, estarán asignando a tu conexión una IP dinámica. Si cada vez utilizas una IP, ¿cómo puedes entonces conectar al servicio? Utilizando un tercer servidor.</p>
<p>Muy posiblemente ya tengas acceso a un servidor remoto con una IP estática y al que tienes acceso SSH (por ejemplo, porque en él tienes alojada una página web). Podremos autorizar a este tercer servidor a ser el único al que se le permita acceder al servicio deseado. De esta forma, tendríamos tres equipos:</p>
<ol>
<li>Por un lado, el <strong>equipo #1</strong>, que es el cliente, el ordenador desde el que inicias la conexión a través de tu línea ADSL o 3G.</li>
<li>Por otro lado, tenemos el <strong>equipo #2</strong>, que es el servidor web al que tienes acceso SSH. Host: <strong>example1.com</strong>.</li>
<li>Y por último, el <strong>equipo #3</strong>, que es el que tiene el servicio que sólo autoriza a unas determinadas direcciones IPs. Host: <strong>example2.com</strong>. El puerto del servicio es, por ejemplo, el 1234.</li>
</ol>
<div>Lo que haríamos sería indicar al administrador de #3 que añada la dirección IP de #2 como una IP autorizada. Entonces, podríamos iniciar un túnel SSH de #1 a #2, configurado para que redirija todo su tráfico a #3:</div>
<pre>$ ssh usuario@example1.com -L 2222:example2.com:1234 -N</pre>
<p>Es decir, primero conectamos mediante SSH al equipo #2 (example1.com). Por otra parte, el parámetro L indica que todo el tráfico que conecte al puerto 2222 del cliente (equipo #1) se redirigirá, mediante la conexión SSH del equipo #2 (example1.com), hasta el puerto 1234 del equipo #3 (example2.com). Por último, el parámetro -N es un modificador que se utiliza en túneles SSH para evitar que se ejecuten comandos en el equipo remoto (equipo #2).</p>
<p>Pulsamos INTRO, introducimos la constraseña de nuestro usuario de example1.com, y ya está. ¿Ahora qué? Si quisiéramos conectar al famoso servicio remoto del equipo #3, tan sólo deberíamos realizar la conexión a localhost:2222, y ya estaríamos dentro.</p>
<p>Espero que este truquito os sea de tanta utilidad como lo es para mí <img src='http://chusete.es/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />
<div class="tweetmeme_button" style="float: left; margin-right: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fchusete.es%2F2011%2F10%2F10%2Fmini-receta-tunel-ssh%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fchusete.es%2F2011%2F10%2F10%2Fmini-receta-tunel-ssh%2F&amp;source=chuso&amp;style=normal&amp;service=bit.ly&amp;service_api=R_86054639b9f90148987197dfdc061697&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
]]></content:encoded>
			<wfw:commentRss>http://chusete.es/2011/10/10/mini-receta-tunel-ssh/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Introducción a la programación en Facebook V</title>
		<link>http://chusete.es/2011/09/23/introduccion-a-la-programacion-en-facebook-v/</link>
		<comments>http://chusete.es/2011/09/23/introduccion-a-la-programacion-en-facebook-v/#comments</comments>
		<pubDate>Fri, 23 Sep 2011 16:27:12 +0000</pubDate>
		<dc:creator>chusete</dc:creator>
				<category><![CDATA[desarrollo]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[php sdk]]></category>
		<category><![CDATA[sdk]]></category>

		<guid isPermaLink="false">http://chusete.es/?p=1221</guid>
		<description><![CDATA[Quinta y última parte de esta guía introductoria al desarrollo de aplicaciones web sobre la Facebook Platform. Ya conoces el ecosistema de tecnologías de Facebook, sabes cómo crear distintos tipos de aplicaciones, y conoces el SDK JavaScript por completo. Hoy vamos a ver el PHP SDK. Antes de seguir leyendo, puedes echar un vistazo a [...]]]></description>
			<content:encoded><![CDATA[<p><img class="aligncenter size-full wp-image-1233" title="head_fb5" src="http://chusete.es/wp-content/uploads/2011/09/head_fb5.png" alt="" width="100%" /></p>
<p>Quinta y última parte de esta guía introductoria al desarrollo de aplicaciones web sobre la Facebook Platform. Ya conoces el ecosistema de tecnologías de Facebook, sabes cómo crear distintos tipos de aplicaciones, y conoces el SDK JavaScript por completo. Hoy vamos a ver el <a href="http://developers.facebook.com/docs/reference/php/">PHP SDK</a>.</p>
<p>Antes de seguir leyendo, puedes echar un vistazo a la página GitHub donde está alojado el <a href="https://github.com/facebook/php-sdk">proyecto PHP SDK</a>, y desde donde te lo podrás <a href="https://github.com/facebook/php-sdk/archives/master">descargar</a>. Nosotros vamos a hablar sobre la última versión estable, la 3.1.0.</p>
<h2><span id="more-1221"></span>1 Instalación</h2>
<p>Ya has dado de alta tus aplicaciones, y ahora quieres saber cómo incorporar el PHP SDK a alguna de ellas. Lo primero, deberás descargarte el SDK de su página en GitHub y descomprimirlo. Verás tres carpetas:</p>
<p><a href="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-22-a-las-21.22.15.png"><img class="aligncenter size-medium wp-image-1222" title="Captura de pantalla 2011-09-22 a la(s) 21.22.15" src="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-22-a-las-21.22.15-300x152.png" alt="" width="300" height="152" /></a></p>
<p>Se incluye:</p>
<ul>
<li><strong>changelog.md</strong> &#8211; Fichero que registra todos los cambios entre las distintas versiones del SDK.</li>
<li><strong>examples</strong> &#8211; Un ejemplo de uso.</li>
<li><strong>readme.md</strong> &#8211; Fichero &#8216;léame&#8217; con documentación básica.</li>
<li><strong>src</strong> &#8211; Bibliotecas del SDK. Esta carpeta es la que usaremos en nuestro proyecto.</li>
<li><strong>tests</strong> -Batería de tests unitarios para comprobar el correcto funcionamiento del SDK.</li>
</ul>
<div>Vamos a crear una nueva carpeta, donde crearemos un fichero index.php y donde copiaremos la carpeta &#8216;src&#8217;:</div>
<div><a href="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-22-a-las-21.28.59.png"><img class="aligncenter size-full wp-image-1223" title="Captura de pantalla 2011-09-22 a la(s) 21.28.59" src="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-22-a-las-21.28.59.png" alt="" width="334" height="122" /></a></div>
<div>Ahora, editaremos el fichero index.php y añadiremos el código de inicialización del PHP SDK:</div>
<div>
<pre class="php" name="code">&lt;?php
    require_once("src/facebook.php");

    $config = array(
        'appId' =&gt; 'TU_APP_ID',
        'secret' =&gt; 'TU_APP_SECRET',
        'fileUpload' =&gt; false, // opcional
    );

    $facebook = new Facebook($config);</pre>
</div>
<p>Es decir, cargamos el SDK, creamos un nuevo array con la configuración del objeto Facebook, y finalmente lo creamos. ¡Ya está! <img src='http://chusete.es/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Ya puedes usar el PHP SDK.</p>
<h2>2 Métodos básicos</h2>
<p>Vamos a ver 6 métodos getter y setter básicos:</p>
<h3><a href="http://developers.facebook.com/docs/reference/php/facebook-getAccessToken/">Facebook::getAccessToken</a></h3>
<p>Mediante este método podremos obtener el accessToken en uso. Los access token son objetos que definen los permisos que tenemos para interactuar con un determinado usuario. Puedes ver más sobre el objeto access_token en la <a href="http://developers.facebook.com/docs/reference/api/permissions/">documentación de los permisos</a>.</p>
<h3><a href="http://developers.facebook.com/docs/reference/php/facebook-setAccessToken/">Facebook::setAccessToken</a></h3>
<p>Del mismo modo, podremos establecer el accessToken con el que funcionará nuestra aplicación. Se sobreentiende que este AccessToken ha sido obtenido por algún medio ajeno al SDK de PHP (por ejemplo, mediante cURL).</p>
<h3><a href="http://developers.facebook.com/docs/reference/php/facebook-getAppSecret/">Facebook::getApiSecret</a></h3>
<p>Nos devuelve el APP_SECRET de la aplicación.</p>
<h3><a href="http://developers.facebook.com/docs/reference/php/facebook-setAppSecret/">Facebook::setApiSecret</a></h3>
<p>Permite establecer a mano el APP_SECRET para nuestra aplicación</p>
<h3><a href="http://developers.facebook.com/docs/reference/php/facebook-getAppId/">Facebook::getAppId</a></h3>
<p>Devuelve el APP_ID de nuestra aplicación</p>
<h3><a href="http://developers.facebook.com/docs/reference/php/facebook-setAppId/">Facebook::setAppId</a></h3>
<p>Nos permite establecer a mano el APP_ID de la aplicación</p>
<h2>3 Métodos de autenticación</h2>
<p>Lo primero es lo primero. Vamos a ver cómo podremos autenticar a un usuario, y cómo solicitarle permisos. Para ello, vamos a revisar antes cuatro métodos más:</p>
<h3><a href="http://developers.facebook.com/docs/reference/php/facebook-getLoginStatusUrl/">Facebook::getLoginStatusUrl</a></h3>
<p>Este método nos permite especificar URLs según el estado de login del usuario, de manera que en función de este estado, nos redirigirá a un URL u otra. Hay tres estados posibles:</p>
<ol>
<li><strong>ok_session</strong> &#8211; El usuario ha iniciado sesión en Facebook.</li>
<li><strong>no_user</strong> &#8211; El usuario no ha iniciado sesión en Facebook.</li>
<li><strong>no_session</strong> &#8211; El usuario no está conectado a nuestra aplicación.</li>
</ol>
<p>El valor devuelto por esta URL es una dirección de Facebook que se encarga de llevar a cabo por nosotros la redirección. Puedes <a href="http://www.chusete.es/facebook/phpdemo/getLoginStatusUrl.php">probar aquí</a> para ver en funcionamiento este ejemplo:</p>
<pre name="code" class="php">    if (isset($_GET['status']) &amp;&amp; !empty($_GET['status'])) {
        switch($_GET['status']) {
            case 1: echo 'Te conozco <img src='http://chusete.es/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> '; break;
            case 2: echo 'No est&amp;aacute;s conectado a Facebook.'; break;
            case 3: echo 'Est&amp;aacute;s conectado, pero no te conozco.'; break;
        }
        echo "&lt;br /&gt;&lt;a href='http://www.chusete.es/facebook/phpdemo/getLoginStatusUrl.php'&gt;Volver a intentar&lt;/a&gt;";
    } else {
        $params = array(
            'ok_session' =&gt; 'http://www.chusete.es/facebook/phpdemo/getLoginStatusUrl.php?status=1',
            'no_user' =&gt; 'http://www.chusete.es/facebook/phpdemo/getLoginStatusUrl.php?status=2',
            'no_session' =&gt; 'http://www.chusete.es/facebook/phpdemo/getLoginStatusUrl.php?status=3',
        );

        header("Location: ".$facebook-&gt;getLoginStatusUrl($params));
    }</pre>
<h3><a href="http://developers.facebook.com/docs/reference/php/facebook-getLoginUrl/">Facebook::getLoginUrl</a></h3>
<p>Construye por nosotros la URL desde la que accedemos a la página que nos muestra el diálogo OAuth. Acepta dos parámetros:</p>
<ol>
<li><strong>scope</strong> &#8211; Como ya sabes, la lista de permisos que queremos solicitar al usuario.</li>
<li><strong>redirect_uri</strong> &#8211; Dirección a la que se redirigirá tras el diálogo OAuth.</li>
</ol>
<div>Por ejemplo:</div>
<div>
<pre name="code" class="php">    $params = array(
        'scope' =&gt; 'read_stream, friends_interests',
        'redirect_uri' =&gt; 'http://chusete.es/post_login_page',
    );

    $loginUrl = $facebook-&gt;getLoginUrl($params);</pre>
<p>De este modo, en <em>$loginUrl</em> tendremos una URL que nos mostrará el diálogo OAuth que solicita al usuario permisos para consultar su muro y para conocer los intereses de sus amigos. Tras aceptarlo, se le redirigirá a la dirección de <em>redirect_url</em>.</p>
</div>
<h3><a href="http://developers.facebook.com/docs/reference/php/facebook-getLogoutUrl/">Facebook::getLogoutUrl</a></h3>
<p>Del mismo modo que podemos generar la URL de inicio de sesión en nuestra aplicación, podemos crear otra para salir. Sólo debemos indicar un parámetro (opcional):</p>
<ul>
<li><strong>next</strong> &#8211; URL a la que se le redirigirá al usuario tras hacer logout.</li>
</ul>
<h3><a href="http://developers.facebook.com/docs/reference/php/facebook-getUser/">Facebook::getUser</a></h3>
<p>Este método tan sólo nos devuelve el ID del usuario activo en nuestra aplicación.</p>
<h2>4 Autenticación</h2>
<p>Ya tienes la aplicación creada, ya has descargado el SDK, ya has instanciado un objeto de la clase Facebook, y ya conoces los métodos necesarios. Es el momento de ver cómo hacer un inicio de sesión en nuestra aplicación <img src='http://chusete.es/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Esto es lo que va a realizar nuestro ejemplo: Cuando el usuario acceda a la aplicación, si ha conectado con ella previamente, se le mostrará un mensaje de bienvenida. En caso contrario, le reenviaremos al diálogo OAuth para solicitarle permisos. Si los acepta, volverá a la aplicación, donde le daremos la bienvenida y le daremos la opción de cerrar sesión. En caso contrario, le mostraremos un mensaje lamentando que no haya conectado con nuestra súper app. Puedes ver <a href="http://chusete.es/facebook/phpdemo/">aquí la demo</a>.</p>
<p>Éste es el código:</p>
<pre name="code" class="php">    $params = array(
        'scope' =&gt; 'read_stream, friends_interests',
        'redirect_uri' =&gt; 'http://chusete.es/facebook/phpdemo/',
    );
    $loginUrl = $facebook-&gt;getLoginUrl( $params );

    if ( $_GET['error'] ) {
        echo "Parece que no quieres usar la aplicaci&amp;oacute;n <img src='http://chusete.es/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> &lt;br /&gt;";
        echo "Si cambias de opini&amp;oacute;n, haz clic &lt;a href='".$loginUrl."'&gt;aqu&amp;iacute;&lt;/a&gt;";
    } elseif( $facebook-&gt;getUser() ) {
        $logoutUrl = $facebook-&gt;getLogoutUrl(array('next' =&gt; 'http://www.facebook.com/'));
        echo "Bienvenido! <img src='http://chusete.es/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> &lt;br /&gt;";
        echo "Puedes &lt;a href='".$logoutUrl."'&gt;cerrar sesi&amp;oacute;n&lt;/a&gt; si lo deseas.";
    } else {
        header( "Location: ".$loginUrl );
    }</pre>
<p>Como de costumbre, vamos a revisarlo:</p>
<ol>
<li>En primer lugar construímos la URL en la que se muestra el <em>diálogo OAuth</em>, generado a partir de unos determinados parámetros:</li>
<ol>
<li>Solicitamos algunos permisos extra: <em>read_stream</em> y <em>friends_interets</em>.</li>
<li>Definimos la URL actual como la dirección a la que debe retornar el <em>diálogo OAuth</em> tras la autorización (o no) del usuario.</li>
</ol>
<li>Ahora seguimos la ejecución. Recuerda que, como hemos definido esta misma URL como dirección de retorno, cuando el usuario autorice (o no) nuestra aplicación, volveremos aquí:</li>
<ol>
<li>Si está presente el parámetro GET &#8216;<em>error</em>&#8216;, significa que el usuario no autorizó la aplicación. En ese caso mostramos un mensaje con una carita triste, y le damos de nuevo la opción de conectar con la aplicación.</li>
<li>En caso contrario, comprobamos si hay algún usuario reconocido. Si así fuera, mostramos un mensaje de bienvenida y un link de <em>logout</em>.</li>
<li>Y si no hubiera ningún usuario reconocido, redirigiríamos automáticamente mediante la función <em>header()</em> a la URL del <em>diálogo OAuth</em> desde la que podrá conectar con la aplicación.</li>
</ol>
</ol>
<h2>5 Resto de métodos</h2>
<p>Lo creas o no, hemos visto prácticamente todos los métodos del PHP SDK. Vamos a revisar los cuatro que nos quedan:</p>
<h3><a href="https://developers.facebook.com/docs/reference/php/facebook-api/">Facebook::api</a></h3>
<p>Método polimórfico que nos permite realizar llamadas al <a href="https://developers.facebook.com/docs/reference/api/">Graph API</a> (incluso con <a href="https://developers.facebook.com/docs/reference/fql/">FQL</a>, el Facebook Query Language). Puede lanzar excepciones de tipo FacebookApiException. Para poder realizar consultas que no sean públicas, debemos asegurarnos previamente de que tenemos permisos suficientes de ese usuario. Puedes probar <a href="http://chusete.es/facebook/phpdemo/api.php">esta demo</a>, de la que tienes a continuación el código:</p>
<pre name="code" class="php">&lt;?php
    require_once("src/facebook.php");

    $config = array(
        'appId' =&gt; '256797284360192',
        'secret' =&gt; '1e4791731181402f02399fbe174cdb0d',
        'fileUpload' =&gt; false, // opcional
    );

    $facebook = new Facebook($config);

    $loginUrl = $facebook-&gt;getLoginUrl();

    $user = $facebook-&gt;getUser();
?&gt;
&lt;html&gt;
    &lt;head&gt;
        &lt;meta charset="UTF-8" /&gt;
    &lt;/head&gt;
    &lt;body&gt;
    &lt;?php
        if($user) {
            try {
                $_SESSION['user_id'] = $user;
                $user_profile = $facebook-&gt;api('/me','GET');
                echo "Nombre: " . $user_profile['name'];
            } catch(FacebookApiException $e) {
                echo "Error. Posiblemente ha expirado la sesión. ";
                echo "&lt;a href='".$loginUrl."'&gt;Volver a iniciar sesión&lt;/a&gt;&lt;br /&gt;";
                $result = $e-&gt;getResult();
                var_dump($result);
            }
        } else {
            echo "Haz clic &lt;a href='".$loginUrl."'&gt;aqu&amp;iacute;&lt;/a&gt; para iniciar sesi&amp;oacute;n";
        }

    ?&gt;
    &lt;/body&gt;
&lt;/html&gt;</pre>
<h3>FacebookApiException</h3>
<p>Cuando realizamos una consulta al API de Facebook mediante Facebook::api, podrán lanzarse excepciones, por lo que cada llamada a Facebook::api deberá ir dentro de su bloque try-catch correspondiente. Las excepciones tendrán estos dos métodos:</p>
<ol>
<li><a href="https://developers.facebook.com/docs/reference/php/exception-getResult/">getResult</a> &#8211; Devuelve un objeto array con el mensaje de error que devuelve el servidor.</li>
<li><a href="https://developers.facebook.com/docs/reference/php/exception-getType/">getType</a> &#8211; Devuelve el tipo de excepción, como por ejemplo <em>OAuthExcepcion</em>.</li>
</ol>
<h3><a href="https://developers.facebook.com/docs/reference/php/facebook-getSignedRequest/">Facebook::getSignedRequest</a></h3>
<p>En la <a href="http://chusete.es/2011/09/22/introduccion-a-la-programacion-en-facebook-iv/">cuarta parte de esta guía</a> vimos qué es el objeto <em><a href="http://developers.facebook.com/docs/authentication/signed_request/">signedRequest</a></em>. Como dijimos, se trata de un objeto que sirve para compartir información entre Facebook y nuestra aplicación. Desde JavaScript no era seguro su uso, ya que, al no deber hacer público el APP_SECRET de una aplicación, no podríamos tener la certeza de que el contenido del objeto <em>signedRequest</em> estuviera realmente firmado por Facebook.</p>
<p>Sin embargo, desde PHP sí podremos, y este método realiza todo el trabajo sucio por nosotros: decodifica, comprueba la firma, y devuelve el objeto en forma de array PHP. De esta forma, con el objeto devuelto por este método podríamos comprobar en una aplicación de tipo <em>Page Tab</em> si el usuario es o no fan (sin necesidad de solicitar ningún permiso).</p>
<p>Consulta la <a href="https://developers.facebook.com/docs/authentication/signed_request/">documentación de signedRequest</a> para más información.</p>
<h3><a href="https://developers.facebook.com/docs/reference/php/facebook-setFileUploadSupport/">Facebook::setFileUploadSupport</a></h3>
<p>Habilita o deshabilita el soporte para subida de ficheros. Éstas se realizarán mediante llamadas al Graph API con el método <strong>Facebook::api</strong> utilizando el método de envío POST. Podemos ver el ejemplo de la documentación de Facebook:</p>
<pre name="code" class="php">$facebook-&gt;setFileUploadSupport(true);

$img = '/tmp/mifoto.png';

$photo = $facebook-&gt;api(
    '/me/photos',
    'POST',
    array(
        'source' =&gt; '@' . $img,
        'message' =&gt; 'Foto subida mediante el SDK de PHP!'
    )
);</pre>
<h3><a href="https://developers.facebook.com/docs/reference/php/facebook-getFileUploadSupport/">Facebook::useFileUploadSupport</a></h3>
<p>Indica si está o no habilitado el soporte para subir ficheros.</p>
<h2>6 Y ahora qué</h2>
<p>Si te has quedado con ganas de más, estás de enhorabuena, porque han quedado muchos conceptos en el tintero.</p>
<p><strong>Otros SDK.</strong> Si tienes pensado desarrollar para Android, puedes echar un vistazo al <a href="https://developers.facebook.com/docs/reference/androidsdk">Android SDK</a>. Puedes hacer también lo propio con el <a href="https://developers.facebook.com/docs/reference/iossdk">iOS SDK</a> si tu intención es crear una aplicación para iPhone o iPad.</p>
<p><a href="http://chusete.es/wp-content/uploads/2011/09/ios4_android.jpg"><img class="aligncenter size-medium wp-image-1230" title="ios4_android" src="http://chusete.es/wp-content/uploads/2011/09/ios4_android-300x175.jpg" alt="" width="300" height="175" /></a></p>
<p><strong>Consultas más eficaces.</strong> Otro asunto interesante por explorar es el <a href="https://developers.facebook.com/docs/reference/fql/">lenguaje FQL</a> para realizar consultas a-la-SQL a Facebook. Mediante este método puedes llevar a cabo comportamientos que con el Graph API no podrías, como ejecutar consultas por lotes.</p>
<p><strong>¡Internacionalizate!</strong> Es otra de las opciones que proporciona Facebook: habilita tu aplicación para que sea traducida, preparándola según las <a href="https://developers.facebook.com/docs/internationalization/">directrices de internacionalización de Facebook</a>.</p>
<p><a href="http://chusete.es/wp-content/uploads/2011/09/i18n_logo.jpg"><img class="aligncenter size-medium wp-image-1231" title="i18n_logo" src="http://chusete.es/wp-content/uploads/2011/09/i18n_logo-300x120.jpg" alt="" width="300" height="120" /></a></p>
<p><strong>Todavía más APIs</strong>&#8230; Tienes a tu alcance <a href="https://developers.facebook.com/docs/reference/ads-api/">Ads API</a>, que te permitirá crear y monitorizar mediante código ambiciosas campañas publicitarias. O <a href="https://developers.facebook.com/docs/creditsapi">Credits API</a>, con la que podrás permitir a tus usuarios comprar créditos de Facebook con los que adquirir nuevas funcionalidades o ítems en tu aplicación. Y <a href="https://developers.facebook.com/docs/chat/">Chat API</a>, con la que podrás incorporar a tu página web, o aplicación nativa, un chat compatible XMPP compatible con Facebook.</p>
<p><strong>Más sobre Graph API</strong>. Si te interesa conocer más acerca de las consultas por lotes, tienes un <a href="https://developers.facebook.com/docs/reference/api/batch/">apartado íntegro</a> dedicado a ellas. Tienes también una <a href="https://developers.facebook.com/docs/reference/api/realtime/">API de actualizaciones en tiempo real</a>.</p>
<p><strong>Juegos</strong>. Lo mencionamos de pasada, pero existe toda una API para que los desarrolladores de videojuegos puedan añadir <a href="https://developers.facebook.com/docs/achievements/">logros</a> y <a href="https://developers.facebook.com/docs/score/">puntuaciones</a>.</p>
<p><strong>Social Design</strong>, es como llaman en Facebook a la forma de pensar cómo crear productos sociales, utilizando tres conceptos clave, comunidad, conversación e identidad. Ver más sobre <a href="https://developers.facebook.com/socialdesign/">Social Design</a>.</p>
<p><strong>Opciones</strong>, muchas más opciones de configuración:</p>
<ul>
<li><strong>Configuración avanzada</strong>:</li>
<ul>
<li>Deauthorize Callback &#8211; Definir una URL a la que se hará un ping cada vez que un usuario se desvincule de tu aplicación (con información en el signedRequest).</li>
<li>Migraciones &#8211; Facebook está en constante cambio. Puedes elegir qué tecnologías usar: las que están en uso o las obsoletas.</li>
<li>Seguridad &#8211; Autorizar determinadas IPs para realizar peticiones en nombre de tu aplicación o para cambiar su configuración. Alertas por email.</li>
<li>Publicidad &#8211; Puedes indicar las direcciones de correo de las cuentas de usuario utilizadas para la publicidad de la página.</li>
<li>Datos de contacto &#8211; Enlaces a las URLs de privacidad, condiciones de uso, de soporte, etc.</li>
</ul>
<li><strong>Roles</strong> &#8211; Desde donde podrás añadir otros usuarios a diferentes perfiles: Desarrollador, tester, usuarios de pruebas (usuarios falsos creados al vuelo), etc.</li>
<li><strong>Credits</strong> &#8211; Donde personalizas los parámetros de configuración necesarios para poder operar con créditos Facebook.</li>
</ul>
<p><strong>Nueva versión de Open Graph</strong>: Hasta ahora podía establecerse un vínculo entre un usuario y otro objeto con el verbo &#8220;me gusta&#8221;. Por ejemplo, &#8220;<em>A Pedro le gusta Coca-Cola</em>&#8220;. Tenemos un <span style="text-decoration: underline;">sujeto</span> (Pedro), una <span style="text-decoration: underline;">acción</span> (gustar), y un <span style="text-decoration: underline;">objeto</span> (Coca-Cola). Hasta ahora el verbo era siempre &#8220;gustar&#8221;. Sin embargo, con esta nueva versión, podrá ser cualquier cualquier cosa: &#8220;<em>María ha tomado un Big Mac</em>&#8220;. Puedes seguir este <a href="https://developers.facebook.com/docs/beta/opengraph/tutorial/">tutorial paso a paso</a>.</p>
<h2><a href="http://chusete.es/wp-content/uploads/2011/09/attachment.jpeg"><img class="aligncenter size-medium wp-image-1232" title="Facebook Open Graph" src="http://chusete.es/wp-content/uploads/2011/09/attachment-300x112.jpg" alt="" width="300" height="112" /></a>7 Resumen</h2>
<p>Con suerte, habrás llegado hasta aquí. Eso significa que ya ha finalizado tu toma de contacto con el desarrollo de aplicaciones en Facebook. Dominas tecnologías básicas como los <strong>social plugins</strong>, <strong>open graph</strong>, o los <strong>diálogos</strong>. Sabes crear distintos tipos de aplicaciones, ya sea en una <strong>web externa</strong>, en un <strong>Canvas</strong>, o en un <strong>Page Tab</strong>. Conoces a fondo el <strong>JavaScript SDK</strong> y el <strong>PHP SDK</strong>. Has tenido una toma de contacto con el <strong>Graph API</strong>. Sabes <strong>autenticar y solicitar permisos</strong> a tus usuarios en cualquier escenario. Eres consciente del <strong>resto de tecnologías de Facebook</strong> que tienes a tu alcance. Sabes qué son los <strong>Social Channels</strong>, y cómo aprovecharlos para dar mayor visibilidad a tus aplicaciones. No está nada mal, ¿no?</p>
<p>Espero que hayas disfrutado de estos artículos tanto como yo, y ojalá puedan serte de utilidad.</p>
<p><strong>¡Muchas gracias por haber seguido esta guía!</strong>.
<div class="tweetmeme_button" style="float: left; margin-right: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fchusete.es%2F2011%2F09%2F23%2Fintroduccion-a-la-programacion-en-facebook-v%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fchusete.es%2F2011%2F09%2F23%2Fintroduccion-a-la-programacion-en-facebook-v%2F&amp;source=chuso&amp;style=normal&amp;service=bit.ly&amp;service_api=R_86054639b9f90148987197dfdc061697&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
]]></content:encoded>
			<wfw:commentRss>http://chusete.es/2011/09/23/introduccion-a-la-programacion-en-facebook-v/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>Introducción a la programación en Facebook IV</title>
		<link>http://chusete.es/2011/09/22/introduccion-a-la-programacion-en-facebook-iv/</link>
		<comments>http://chusete.es/2011/09/22/introduccion-a-la-programacion-en-facebook-iv/#comments</comments>
		<pubDate>Thu, 22 Sep 2011 01:56:05 +0000</pubDate>
		<dc:creator>chusete</dc:creator>
				<category><![CDATA[desarrollo]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://chusete.es/?p=1186</guid>
		<description><![CDATA[En la primera parte vimos una introducción a las tecnologías usadas para programar en Facebook. En la segunda, creamos una aplicación, y le añadimos algún Social Plugin y etiquetas Open Graph. En el tercero, nos zambullimos en el SDK JavaScript, y autenticamos al usuario en nuestra aplicación, le solicitamos permisos extra, publicamos en su muro, [...]]]></description>
			<content:encoded><![CDATA[<p><img class="aligncenter size-full wp-image-1216" title="facebook_dev_wallpaper" src="http://chusete.es/wp-content/uploads/2011/09/facebook_dev_wallpaper.jpg" alt="" width="100%" /></p>
<p>En la primera parte vimos una introducción a las tecnologías usadas para programar en Facebook. En la segunda, creamos una aplicación, y le añadimos algún Social Plugin y etiquetas Open Graph. En el tercero, nos zambullimos en el SDK JavaScript, y autenticamos al usuario en nuestra aplicación, le solicitamos permisos extra, publicamos en su muro, y mostramos algún diálogo.</p>
<p>Hasta ahora hemos trabajado sobre una aplicación que funcione sobre nuestra página web. Sin embargo, como ya sabes, Facebook nos da más opciones: aplicaciones en móviles, y aplicaciones dentro de Facebook. Hoy vamos a ver cómo crear una aplicación dentro de Facebook. Esto se hace mediante un canvas (iframe) en Facebook en el que se mostrará la página web que deseemos. Por supuesto, en esa página web podremos gestionar JavaScript, CSS y HTML como queramos.</p>
<p><span id="more-1186"></span></p>
<h2>Dar de alta la aplicación Canvas</h2>
<p>Vamos a configurar nuestra aplicación. Simplemente accedemos a <a href="https://developers.facebook.com/apps">Aplicaciones</a>, seleccionamos la que deseemos, pulsamos sobre <em>Edit Settings,</em> desplegamos <em>App on Facebook</em> en la parte inferior, y establecemos la URL en la que colgaremos nuestra aplicación canvas (¡Recuerda que a partir del 1 de octubre de 2011 será obligatorio que tus aplicaciones canvas estén disponibles mediante HTTPS!):</p>
<p><a href="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-21-a-las-00.07.18.png"><img class="aligncenter size-medium wp-image-1188" title="Captura de pantalla 2011-09-21 a la(s) 00.07.18" src="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-21-a-las-00.07.18-300x53.png" alt="" width="300" height="53" /></a></p>
<p>¿Te has fijado que bajo las dos URLs hay un tercer campo donde pone <em>Canvas Page</em>? Es la dirección de Facebook desde donde se podrá acceder a tu aplicación canvas. Como ves, para construir la URL han usado el <em>App Namespace</em> que estableciste cuando diste de alta la aplicación en la segunda parte de esta guía.</p>
<p>En las aplicaciones Canvas tenemos disponibles nuevos métodos del SDK JavaScript. Algunos de ellos son:</p>
<h3><a href="http://developers.facebook.com/docs/reference/javascript/FB.Canvas.getPageInfo/">FB.Canvas.getPageInfo</a></h3>
<p>Un iframe, por seguridad, no puede acceder a los parámetros del documento raíz (window), por lo que, a priori, no hay forma de conocer algunos parámetros como son el tamaño del canvas o las coordenadas del scroll. Este método se salta esa restricción (solicitándoselo por HTTP a Facebook), y nos devuelve toda esa información:</p>
<ul>
<li><strong>clientHeight</strong> &#8211; Altura en píxels de la zona visible del navegador.</li>
<li><strong>clientWidth</strong> &#8211; Ancho en píxels de la zona visible del navegador.</li>
<li><strong>offsetLeft</strong> &#8211; Distancia entre el borde izquierdo del canvas y el borde izquierdo de la página de Facebook.</li>
<li><strong>offsetTop</strong> &#8211; Distancia entre el borde superior del canvas y el borde superior de la página de Facebook.</li>
<li><strong>scrollLeft</strong> &#8211; Desplazamiento del scroll izquierdo.</li>
<li><strong>scrollTop</strong> &#8211; Desplazamiento del scroll derecho.</li>
</ul>
<p>Echa un vistazo a <a href="http://apps.facebook.com/chusetedemo/?step=1">este ejemplo</a> para entender mejor cada valor.</p>
<h3><a href="http://developers.facebook.com/docs/reference/javascript/FB.Canvas.setDoneLoading/">FB.Canvas.setDoneLoading</a></h3>
<p>Esta función indica el tiempo de carga de la aplicación (debes colocarlo en un punto en el cual consideres que la aplicación está lista para funcionar). Al invocarla, se enviará el resultado a Facebook Insights (las métricas de las aplicaciones y Facebook Pages) para que puedas hacerte una idea de cuánto tiempo lleva a tus usuarios cargar tu aplicación.</p>
<h3><a href="http://developers.facebook.com/docs/reference/javascript/FB.Canvas.startTimer/">FB.Canvas.startTimer</a></h3>
<p>Para usar junto con FB.Canvas.setDoneLoading. Indica el comienzo de un rango de tiempo que no se incluirá dentro del tiempo total de carga de la página.</p>
<h3><a href="http://developers.facebook.com/docs/reference/javascript/FB.Canvas.stopTimer/">FB.Canvas.stopTimer</a></h3>
<p>Junto con FB.Canvas.startTimer, indica el final del rango de tiempo que no se debe tener en cuenta para el cálculo total de tiempo.</p>
<h3><a href="http://developers.facebook.com/docs/reference/javascript/FB.Canvas.setUrlHandler/">FB.Canvas.setUrlHandler</a></h3>
<p>Alrededor de una aplicación hay diversos enlaces (a teletipos, marcadores, peticiones en el desplegable de marcadores, peticiones en el panel de notificaciones). Este método permite que, cuando un usuario haga clic en uno de esos enlaces, una función callback capture esa petición y realice alguna otra operación. Por ejemplo, si en un juego el usuario hace clic en un teletipo sobre un logro de un jugador, se podría capturar la petición y en lugar de redireccionar, mostrar el logro dentro de la aplicación.</p>
<h2>Tamaño de la aplicación</h2>
<p>Nuestra aplicación, lógicamente, tendrá un ancho y un alto. ¿Y si excede el ancho máximo que Facebook nos permite? ¿Y si su alto crece dinámicamente? Para lidiar con esto, vamos a ir a la configuración avanzada de nuestra aplicación, donde veremos esto:</p>
<p><a href="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-21-a-las-00.35.01.png"><img class="aligncenter size-medium wp-image-1189" title="Captura de pantalla 2011-09-21 a la(s) 00.35.01" src="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-21-a-las-00.35.01-300x42.png" alt="" width="300" height="42" /></a></p>
<p>Nos dan la opción de elegir cómo se comportará el ancho y el alto del canvas.</p>
<h3>Ancho (Canvas Width)</h3>
<p>Tenemos dos opciones:</p>
<ol>
<li><strong>Fixed (760px)</strong>. Es decir, el ancho será de tamaño fijo, establecido en 760 píxels.</li>
<li><strong>Fluid</strong>. El canvas (junto con toda la web de Facebook) se ajusta al ancho máximo que permita la ventana.</li>
</ol>
<h3>Alto (Canvas Height)</h3>
<p>De nuevo, tenemos dos opciones:</p>
<ol>
<li><strong>Ajustable (800px)</strong>. En este caso, se establece un tamaño fijo (por defecto 800px).</li>
<li><strong>Fluid.</strong> El canvas ocupará el 100% del alto permitido. En caso de que exceda el alto asignado a la página, se mostrarán barras de desplazamiento en el canvas.</li>
</ol>
<p>Junto con el modo de alto &#8216;<em>Ajustable (800px)</em>&#8216;, tenemos 3 métodos más del SDK JavaScript (y los últimos):</p>
<h3><a href="http://developers.facebook.com/docs/reference/javascript/FB.Canvas.setSize/">FB.Canvas.setSize</a></h3>
<p>Este método nos permite modificar en tiempo de ejecución la altura del canvas. Si en la configuración del ancho se estableció &#8216;<em>Fixed (760px)</em>&#8216;, no se podrá exceder ese valor. Si no le pasamos ningún parámetro, tratará de determinar automáticamente el tamaño del canvas.</p>
<h3><a href="http://developers.facebook.com/docs/reference/javascript/FB.Canvas.setAutoResize/">FB.Canvas.setAutoResize</a></h3>
<p>Sirve para que el alto se autoajuste dinámicamente (por defecto, cada 100 milisegundos realiza un reajuste). En resumen, inicia un timer que invoca a FB.Canvas.setSize sin ningún parámetro.</p>
<p>Si la aplicación decrece de tamaño, el canvas no decrecerá.</p>
<h3><a href="http://developers.facebook.com/docs/reference/javascript/FB.Canvas.scrollTo/">FB.Canvas.scrollTo</a></h3>
<div>Mueve la posición de la página (las barras de desplazamiento) a las coordenadas (x,y) deseadas.</div>
<h2>Ejemplos</h2>
<p>Vamos a ver algunos ejemplos para comprobar cómo manejar los métodos del SDK JavaScript para el tamaño del Canvas. Usaremos como valor de ancho &#8216;<em>Fixed (760px)</em>&#8216;, y de alto &#8216;<em>Ajustable (800px)</em>&#8216;.</p>
<ol>
<li>En el primer ejemplo vamos a ver una aplicación con 1500px de alto. Verás que no se visualiza el final de la aplicación. <a href="http://apps.facebook.com/chusetedemo/?step=2">Ver ejemplo</a>.</li>
<li>En el segundo ejemplo llamaremos a FB.Canvas.setSize, sin ningún parámetro, para que determine él solo el tamaño de la aplicación, y lo defina en el canvas. <a href="http://apps.facebook.com/chusetedemo/?step=3">Ver ejemplo</a>.</li>
<li>En el tercer ejemplo, tendremos un div que se expande y se contrae. El canvas no se ajustará a su tamaño pese a que llamemos a FB.Canvas.setSize al comenzar su ejecución. <a href="http://apps.facebook.com/chusetedemo/?step=4">Ver ejemplo</a>.</li>
<li>Por último, en el cuarto ejemplo, tenemos de nuevo un div que se expande y se contrae. Sin embargo, en este caso el canvas sí se ajusta a su tamaño. Invocamos a FB.Canvas.setSize cada vez que se modifica el tamaño (esto no siempre será una opción válida, por lo que quizás convenga llamar a FB.Canvas.setAutoResize). <a href="http://apps.facebook.com/chusetedemo/?step=5">Ver ejemplo</a>.</li>
</ol>
<p>Si quieres ver un how-to de cómo realizar aplicaciones fluidas (ancho y alto), revisa <a href="http://developers.facebook.com/blog/post/549/">este post</a> del blog de desarrolladores de Facebook.</p>
<h2>Autenticación y permisos</h2>
<p>Si quisiéramos que los usuarios se autenticaran en nuestra aplicación canvas, y además poder solicitarles permisos, lo haríamos de un modo muy similar a como lo hicimos en la aplicación web. En este ejemplo, la principal diferencia es que en lugar de recurrir al SDK JavaScript para añadir el social plugin &#8220;Entrar&#8221; (y de ese modo, mostrar el diálogo OAuth que solicita permisos), redirigiremos al usuario a una URL que únicamente muestra diálogo OAuth para solicitar los permisos.</p>
<p>Vamos a ver el código:</p>
<pre name="code" class="html">&lt;html&gt;
&lt;head&gt;
&lt;meta charset="UTF-8" /&gt;
&lt;/head&gt;
&lt;body style="background-color: yellow; margin:0 auto; padding:20px;"&gt;
    &lt;div style="height: 500px; background:#EEEEFF; padding: 10px;"&gt;
        &lt;h1&gt;Canvas app&lt;/h1&gt;
        &lt;p id="step1" style="display: none;"&gt;Estás desconectado de esta aplicación. Pulsa &lt;a href="#" onclick="connect()"&gt;aquí&lt;/a&gt; para conectar y acceder al contenido privado.&lt;/p&gt;
        &lt;p id="step2" style="display: none;"&gt;Estás en el contenido privado de esta aplicación <img src='http://chusete.es/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />
        &lt;br /&gt;&lt;br /&gt;Si ya habías concedido permisos a esta aplicación, puedes borrarlos en los &lt;a href="http://www.facebook.com/settings/?tab=applications" target="_blank"&gt;ajustes de aplicaciones&lt;/a&gt; para ver el diálogo OAuth.&lt;/p&gt;
    &lt;/div&gt;
    &lt;div id="fb-root"&gt;&lt;/div&gt;
    &lt;script type="text/javascript" src="http://connect.facebook.net/es_ES/all.js"&gt;&lt;/script&gt;
    &lt;script type="text/javascript"&gt;
        FB.init({
            appId  : '256797284360192',
            status : true, // comprobar estado de login
            cookie : true, // habilitar cookies para permitir al servidor acceder a la sesión
            xfbml  : true, // ejecutar código XFBML
            channelURL : 'http://chusete.es/facebook/channel.html', // fichero channel.html
            oauth  : true // habilita OAuth 2.0
        });

        FB.getLoginStatus(function(response) {
            if (response.authResponse) {
                document.getElementById('step2').style.display = 'block';
            } else {
                document.getElementById('step1').style.display = 'block';
            }
        });

        function connect() {
            top.location.href = 'https://www.facebook.com/dialog/oauth?client_id=256797284360192&amp;redirect_uri=http://apps.facebook.com/chusetedemo/&amp;scope=publish_stream'
        }
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
<p>Como ves, se trata de un documento HTML básico, que muestra un div con dos párrafos (los dos ocultos por defecto). El resto, es código JavaScript.</p>
<p>Vamos a analizar este código:</p>
<ol>
<li>En primer lugar, cargamos el SDK JavaScript.</li>
<li>Después, realizamos una llamada a FB.getLoginStatus, que, como ya sabemos, nos sirve para determinar si el usuario ha conectado o no con nuestra aplicación. En caso afirmativo, mostramos el párrafo cuyo id es &#8216;step2&#8242;. En caso negativo, mostramos el párrafo con id &#8216;step1&#8242;.</li>
<li>El párrafo &#8216;step1&#8242; tiene un link para que los usuarios conecten con la aplicación. Cuando lo pulsan, se ejecuta la función &#8216;connect()&#8217;, cuyo único cometido es redirigir a la URL del diálogo OAuth. La estructura de esta URL es la siguiente:
<pre name="code" class="html">https://www.facebok.com/dialog/oauth?client_id=APP_ID&amp;redirect_uri=APP_URL&amp;scope=PERMISOS</pre>
<p>Por supuesto, existen más parámetros GET que los que hemos usado. Puedes consultarlos todos en la <a href="https://developers.facebook.com/docs/reference/dialogs/oauth/">documentación del diálogo OAuth</a>.</li>
</ol>
<div id="attachment_1190" class="wp-caption aligncenter" style="width: 310px"><a href="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-21-a-las-03.03.41.png"><img class="size-medium wp-image-1190" title="Captura de pantalla 2011-09-21 a la(s) 03.03.41" src="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-21-a-las-03.03.41-300x184.png" alt="" width="300" height="184" /></a><p class="wp-caption-text">Diálogo OAuth que se muestra al redirigir a su URL</p></div>
<p>Una vez que el usuario está autenticado, y nos ha concedido permisos, podríamos hacer como en el ejemplo de la tercera parte, y publicar una historia en su muro.</p>
<div class="note">
<h3>Acerca de top.location.href</h3>
<p>Si te fijas, para enlazar a la URL del diálogo OAuth, hemos usado top.location.href. Si hubiéramos enlazado de forma directa, la redirección se habría realizado dentro del canvas, y no en la ventana principal (top).</p>
<p>Del mismo modo, también podríamos haber hecho esto sin JavaScript, poniendo la URL de destino en el atributo href del elemento &lt;A&gt;, y añadiendo el atributo target con el valor &#8216;_top&#8217;:</p>
<pre name="code" class="html">&lt;a href="https://www.facebook.com/dialog/oauth?client_id=<strong>APP_ID</strong>&amp;redirect_uri=<strong>APP_URL</strong>&amp;scope=<strong>PERMISOS</strong>" target="_top"&gt;</pre>
</div>
<h2>Social Channels</h2>
<p>¿Pensabas que ya conocías todos los conceptos de Facebook? ¡Todavía no! Te presento los <a href="http://developers.facebook.com/docs/channels">Social Channels</a>. Se trata de un concepto que englobal todas las herramientas que Facebook pone a disposición de los desarrolladores para ayudar a que los usuarios compartan las aplicaciones con sus amigos. En resumen, herramienta para ayudar a que tus usuario promocionen y no dejen de usar tu aplicación.</p>
<p>Éstas son los canales de las que dispones:</p>
<ul>
<li><strong>Muro</strong> &#8211; Ya conoces el muro. Es el principal lugar donde compartes publicaciones de cualquier tipo con tus amigos. Como programador, puedes solicitar permisos al usuario para publicar historias en su nombre (como ya sabes, con el permiso publish_stream), o puedes mostrarle un <a href="http://developers.facebook.com/docs/reference/dialogs/feed/">diálogo Feed</a> para que lo haga él. Por otra parte, el <a href="http://developers.facebook.com/docs/reference/plugins/like/">botón &#8216;Me gusta&#8217;</a> también permite que se comparta un contenido en el muro.</li>
<li><strong>Peticiones</strong> &#8211; Permite que los usuarios envíen invitaciones a sus amigos para que utilicen tu aplicación. Al igual que con el muro, puedes solicitar permisos al usuario para enviar peticiones en su nombre (con el permiso apprequest), o bien dejar que lo realice él con el <a href="http://developers.facebook.com/docs/reference/dialogs/requests/">diálogo de peticiones</a>.</li>
<li><strong>Juegos</strong> &#8211; Si estás desarrollando un juego, dentro del Graph API tienes opciones para administrar los <a href="http://developers.facebook.com/docs/achievements/">logros</a> o las <a href="http://developers.facebook.com/docs/score/">puntuaciones</a> de tus usuarios, para de esta forma hacer al juego más competitivo. Puedes revisar este post del blog de desarrolladores de Facebook para conocer más sobre <a href="http://developers.facebook.com/blog/post/539/">cómo publicar logros y puntuaciones de usuarios</a>.</li>
<li><strong>Marcadores</strong> &#8211; Es el enlace a las aplicaciones que se muestra en la columna izquierda de la página principal de Facebook.</li>
<li><strong>Paneles</strong> &#8211; Hay dos paneles de aplicaciones. El <a href="http://www.facebook.com/?sk=apps">panel de aplicaciones</a> propiamente dicho y el <a href="http://www.facebook.com/games">panel de juegos</a>. Desde estos paneles, se muestran recomendaciones, invitaciones, y catálogos de aplicaciones.</li>
<li><strong>Página de perfil de aplicaciones</strong> &#8211; Tal como vimos en la segunda parte, cada vez que damos de alta una nueva aplicación, automáticamente se crea su página de perfil. Desde aquí, podrás escribir novedades y actualizaciones que recibirán tus usuarios.</li>
</ul>
<h2>Pestañas de páginas</h2>
<p>Hay un segundo tipo de aplicaciones canvas que puedes utilizar: las <em>Page Tabs</em>. Son aquellas aplicaciones que se muestran como una <em>pestaña</em> dentro de una Facebook Page. Por ejemplo, accede a la <a href="http://www.facebook.com/cocacola?v=app_161193133389">Facebook Page de Coca-Cola</a>, y verás que dentro de la página de Coca-Cola hay una aplicación.</p>
<p>Ahora vamos a revisar los principales puntos de las <em>Page Tabs</em>.</p>
<h3>Diseño</h3>
<p>En la siguiente imagen puedes ver dónde va ubicada una aplicación de tipo page tab:</p>
<p><a href="http://chusete.es/wp-content/uploads/2011/09/attachment.png"><img class="aligncenter size-medium wp-image-1194" title="attachment" src="http://chusete.es/wp-content/uploads/2011/09/attachment-300x133.png" alt="" width="300" height="133" /></a>Abre la imagen y fíjate en estas cosas:</p>
<ul>
<li>El hueco central está disponible para tu aplicación. Pero en este caso, a diferencia de una aplicación canvas normal, dispondrás de un ancho máximo de 520px.</li>
<li>El título de la página ahora es<br />
&#8220;NOMBRE_PAGINA ᐅ NOMBRE_PAGE_TAB&#8221;.<br />
Al configurar la <em>Page Tab</em> podrás definir con qué nombre aparecerá.</li>
<li>En la columna izquierda aparece el enlace para la <em>Page Tab</em>, con el nombre que, como veremos a continuación, hayamos establecido en su configuración.</li>
</ul>
<h3>Configuración</h3>
<p>Para configurarla, debemos acceder al apartado <a href="https://developers.facebook.com/apps">Aplicaciones</a>, seleccionamos la que deseemos y pulsamos sobre <em>Edit Settings</em>. Esta vez, en el panel inferior desplegaremos <em>Page Tab</em>:</p>
<p><a href="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-22-a-las-02.05.22.png"><img class="aligncenter size-medium wp-image-1195" title="Captura de pantalla 2011-09-22 a la(s) 02.05.22" src="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-22-a-las-02.05.22-300x64.png" alt="" width="300" height="64" /></a>Vemos cuatro campos:</p>
<ol>
<li><strong>Page Tab Name</strong> &#8211; Corresponde al nombre de la aplicación. Será el nombre con el que se cree el enlace dentro de las Facebook Pages, y el que aparecerá en el título.</li>
<li><strong>Page Tab URL</strong> &#8211; Dirección URL donde se podrá localizar la aplicación.</li>
<li><strong>Secure Page Tab URL</strong> &#8211; Dirección URL mediante HTTPS donde se podrá localizar la aplicación. A partir del 1 de octubre de 2011, será obligatoria.</li>
<li><strong>Page Tab Edit URL</strong> &#8211; Dirección URL accesible para los administradores de las Facebook Pages desde donde se les podrá ofrecer un panel de control para personalizar la aplicación.</li>
</ol>
<h3>Añadir a una página</h3>
<p>Una vez tengamos la aplicación creada, querremos que se muestre en alguna de nuestras Facebook Pages. Esto, que pudiera parecer algo trivial, no lo es tanto, pues se encuentra un poco escondido. Deberemos acceder a la página de perfil de nuestra aplicación, en la columna izquierda localizamos el link donde pone &#8220;Añadir a mi página&#8221;, y seleccionamos aquélla en la que lo queramos añadir.</p>
<div class="note">
<h3>Página de perfil de una aplicación</h3>
<p>Como vimos en la segunda parte de esta guía, cada vez que damos de alta una aplicación, se crea junto con ella una página de perfil. Para acceder a ella lo más fácil es ir a la configuración de la aplicación, y desde la columna izquierda hacemos clic sobre <em>View App Profile Page</em>. En el caso de mi aplicación de pruebas, su URL será<br />
<a href="http://www.facebook.com/apps/application.php?id=256797284360192">http://www.facebook.com/apps/application.php?id=256797284360192</a>.</p>
</div>
<h3>Diferencias</h3>
<p>El desarrollo de aplicaciones en <em>Page Tabs</em> es exactamente igual que el de las aplicaciones canvas normales; es decir, podremos añadir el código HTML, CSS y JavaScript que deseemos. Igualmente, podemos hacer uso del SDK JavaScript para autenticar al usuario, solicitar permisos, realizar consultas al Graph API, mostrar diálogos, etc.</p>
<p>Pero tenemos algunos nuevos parámetros disponibles. En el objeto <strong>signedRequest</strong>, se añadirá un nuevo parámetro &#8216;page&#8217; que contiene lo siguiente:</p>
<ul>
<li><strong>id</strong> &#8211; ID de la página actual.</li>
<li><strong>admin</strong> &#8211; Indicando si el usuario es o no administrador de la página.</li>
<li><strong>liked</strong> &#8211; Indica si al usuario le gusta o no la página (sin necesidad de permisos).</li>
</ul>
<p>Además, para personalizar el contenido de la aplicación, podríamos añadir el parámetro GET <em>app_data</em> a la URL principal de Facebook a la que se accede. El valor de este parámetro se traspasará también al objeto signedRequest.</p>
<div class="note">
<h3>signedRequest</h3>
<p>Hasta ahora no hemos hablado de este objeto. Como puedes ver en la <a href="http://developers.facebook.com/docs/authentication/signed_request/">documentación oficial</a>, sirve para, en determinados escenarios, compartir información entre Facebook y nuestra aplicación. De entre la información disponible está:</p>
<ul>
<li><strong>user</strong> &#8211; Datos básicos del usuario.</li>
<li><strong>algorithm</strong> &#8211; Algoritmo con el que se ha firmado.</li>
<li><strong>issued_at</strong> &#8211; Fecha en la que se ha firmado.</li>
<li><strong>user_id</strong> &#8211; Identificador del usuario actual.</li>
<li><strong>oauth_token</strong> &#8211; cadena de texto que se puede usar para realizar peticiones al Graph API.</li>
<li><strong>expires</strong> &#8211; Fecha en que expira el objeto.</li>
<li><strong>app_data</strong> &#8211; Contenido del parámetro GET <em>app_data</em>.</li>
<li><strong>page</strong> &#8211; Información disponible para las Page Tabs.</li>
<li><strong>profile_id</strong> &#8211; En caso de que la aplicación esté dentro de una página, y se haya creado con FBML, contendrá el ID de la página.</li>
</ul>
<p>Este objeto JSON viene codificado en base64, y firmado con <a href="http://en.wikipedia.org/wiki/HMAC">HMAC</a> y <a href="http://en.wikipedia.org/wiki/SHA-2">SHA-256</a> usando el <em>App Secret </em>(el código secreto que se generó al dar de alta la aplicación). Gracias a esto sabremos que la petición está firmada por Facebook, y no por terceras partes. Si hiciéramos público el App Secret, o si no comprobáramos la firma, no tendríamos esa certeza. Por esa razón, está completamente desaconsejado acceder a los parámetros de signedRequest desde JavaScript. Cuando veamos el SDK PHP veremos cómo revisar estos campos.</p>
<p>En cualquier caso, si quisieras acceder a la cadena de texto codificada de signedRequest en JavaScript, podrás hacerlo mediante el objeto response que devuelve el método <a href="http://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus/">FB.getLoginStatus</a>. Puedes imprimirlo en el log de la consola JavaScript (console.log) para ver el contenido completo de este objeto.</p>
</div>
<h2>Resumen</h2>
<p>Ya habíamos visto los principales conceptos de Facebook, cómo crear una aplicación, cómo usar plugins sociales, y cómo utilizar Open Graph. También revisamos prácticamente todo el SDK JavaScript, viendo cómo iniciar sesión, solicitar permisos, y realizar acciones mediante el Graph API.</p>
<p>Esta vez, hemos visto cómo crear otro tipo de aplicaciones; las aplicaciones canvas que se muestran dentro de Facebook, y que también se pueden incorporar como pestaña de una Facebook Page. Hemos terminado de ver el resto de métodos del SDK JavaScript, que nos permiten gestionar asuntos relacionados con Canvas. Del mismo modo, hemos realizado una autenticación y solicitud de permisos equivalente a la de una aplicación web, pero esta vez dentro de canvas. Tambien conocemos ahora un nuevo objeto, signedRequest, que permite que Facebook comparta información con nuestra aplicación. Y, además, hemos revisado las herramientas que Facebook pone a nuestra disposición para promocionar nuestras aplicaciones: los Social Channels.</p>
<p>Si has llegado hasta aquí, ya tendrás bastante soltura desarrollando aplicaciones para Facebook. En la siguiente, y última parte, veremos cómo usar el SDK de PHP. ¡Hasta pronto!
<div class="tweetmeme_button" style="float: left; margin-right: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fchusete.es%2F2011%2F09%2F22%2Fintroduccion-a-la-programacion-en-facebook-iv%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fchusete.es%2F2011%2F09%2F22%2Fintroduccion-a-la-programacion-en-facebook-iv%2F&amp;source=chuso&amp;style=normal&amp;service=bit.ly&amp;service_api=R_86054639b9f90148987197dfdc061697&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
]]></content:encoded>
			<wfw:commentRss>http://chusete.es/2011/09/22/introduccion-a-la-programacion-en-facebook-iv/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Introducción a la programación en Facebook III</title>
		<link>http://chusete.es/2011/09/18/introduccion-a-la-programacion-en-facebook-iii/</link>
		<comments>http://chusete.es/2011/09/18/introduccion-a-la-programacion-en-facebook-iii/#comments</comments>
		<pubDate>Sun, 18 Sep 2011 00:50:00 +0000</pubDate>
		<dc:creator>chusete</dc:creator>
				<category><![CDATA[desarrollo]]></category>
		<category><![CDATA[javasctipt]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[graph api]]></category>
		<category><![CDATA[sdk javascript]]></category>

		<guid isPermaLink="false">http://chusete.es/?p=1161</guid>
		<description><![CDATA[Tercera parte de esta guía de introducción a la programación de aplicaciones en Facebook. Si seguiste la primera y la segunda parte, a estas alturas ya le habrás perdido el medio a muchos de los conceptos clave (tipos de aplicaciones, SDKs, Social Plugins, Open Graph, XFBML, Insights). Pero hay otros conceptos igualmente importantes que todavía [...]]]></description>
			<content:encoded><![CDATA[<p><img class="aligncenter size-full wp-image-1176" title="photos-facebook-f8-developers-conference-2008_1-550x331" src="http://chusete.es/wp-content/uploads/2011/09/photos-facebook-f8-developers-conference-2008_1-550x331.jpg" alt="" width="100%" />Tercera parte de esta guía de introducción a la programación de aplicaciones en Facebook. Si seguiste la <a href="/2011/09/13/introduccion-a-la-programacion-en-facebook/">primera</a> y la <a href="/2011/09/16/introduccion-a-la-programacion-facebook-ii/">segunda</a> parte, a estas alturas ya le habrás perdido el medio a muchos de los conceptos clave (tipos de aplicaciones, SDKs, Social Plugins, Open Graph, XFBML, Insights). Pero hay otros conceptos igualmente importantes que todavía no conocemos. Hoy vamos a tratar la autenticación OAuth, el SDK de JavaScript a fondo, y veremos cómo crear diálogos.</p>
<p><span id="more-1161"></span></p>
<h2>Paso 1 &#8211; Autenticación</h2>
<p>Vamos a añadir un sistema de autenticación mediante el Social Plugin &#8216;Login Button&#8217;, el diálogo OAuth, y el protocolo de autenticación OAuth. No te asustes, pues tras tanta palabreja se esconde una única línea de código HTML <img src='http://chusete.es/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<div class="note">
<h3>OAuth</h3>
<p><a href="http://es.wikipedia.org/wiki/OAuth">OAuth</a> es un protocolo estándar que permite realizar autenticación segura contra una determinada API. Facebook en concreto se ciñe al estándar <a href="http://oauth.net/2/">OAuth 2.0</a>. Gracias a las herramientas que nos ofrece Facebook, no será necesario que conozcamos los entresijos de este protocolo, pero como siempre, sí es muy recomendable conocerlo.</p>
</div>
<p>En primer lugar, vamos a crear el <a href="https://developers.facebook.com/docs/reference/plugins/login/">Login Button</a>. Como ya sabemos, accedemos a la página del plugin, completamos el formulario, y obtenemos su código HTML, que será similar a éste:</p>
<pre name="code" class="html">&lt;div class="fb-login-button" data-show-faces="false" data-width="200" data-max-rows="1"&gt;&lt;/div&gt;</pre>
<p>Con sólo poner eso, ya tendremos el Login Button <a href="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-17-a-las-01.55.56.png"><img class="alignnone size-full wp-image-1162" title="Captura de pantalla 2011-09-17 a la(s) 01.55.56" src="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-17-a-las-01.55.56.png" alt="" width="71" height="23" /></a>. ¿Y qué ocurrirá cuando lo pulsemos? Se desplegará automáticamente un <a href="http://developers.facebook.com/docs/reference/dialogs/oauth/">diálogo OAuth</a> (¿recuerdas los diálogos? Hablamos sobre ellos en la <a href="/2011/09/13/introduccion-a-la-programacion-en-facebook/">primera parte</a>) que nos solicitará permiso para que la aplicación pueda acceder a nuestra información básica:</p>
<p><a href="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-17-a-las-01.54.41.png"><img class="aligncenter size-medium wp-image-1163" title="Captura de pantalla 2011-09-17 a la(s) 01.54.41" src="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-17-a-las-01.54.41-300x183.png" alt="" width="300" height="183" /></a>Con esto quizás sea suficiente. Pero vamos a enriquecerlo un poco, y en lugar de solicitar sólo la información básica, vamos a pedir permisos también para poder publicar nuevas noticias en su muro. Si recuerdas, en el apartado &#8220;Autenticación y permisos&#8221; de la primera parte de esta guía, hablamos de los distintos tipos de permisos. Puedes volver a consultar la <a href="http://developers.facebook.com/docs/reference/api/permissions/">lista completa</a> de todos los que hay disponibles. En concreto el permiso para publicar en el muro se llama &#8216;publish_stream&#8217;. Para solicitarlo, debemos actualizar el código que genera el Loggin Button añadiendo el atributo &#8216;scope&#8217; (puedes ver más sobre los atributos de Login Button en <a href="https://developers.facebook.com/docs/reference/plugins/login/">su documentación</a>). Nos quedaría así:</p>
<pre name="code" class="html">&lt;div class="fb-login-button" data-show-faces="false" data-width="200" data-max-rows="1" scope="publish_stream" &gt;&lt;/div&gt;</pre>
<p>Y el nuevo diálogo OAuth:</p>
<p><a href="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-17-a-las-02.08.36.png"><img class="aligncenter size-medium wp-image-1164" title="Captura de pantalla 2011-09-17 a la(s) 02.08.36" src="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-17-a-las-02.08.36-300x181.png" alt="" width="300" height="181" /></a></p>
<p>Como vemos, ha funcionado correctamente, y ahora también solicita permisos para publicar en el muro. <a href="http://chusete.es/facebook/step2_1.html">Ver ejemplo</a>.</p>
<div class="note">
<h3>Atributo &#8216;scope&#8217;</h3>
<p>Al código HTML que de define el Login Button le hemos añadido un atributo llamado &#8216;scope&#8217; en el que podemos añadir una lista de permisos, de entre todos los disponibles, separados por comas. Estos permisos serán los que se soliciten cuando se despliegue el diálogo OAuth.</p>
<p>Mientras se escribe esta guía, en la documentación oficial del Login Button no hay mención a un atributo llamado &#8216;scope&#8217;. Sin embargo, sí hablan del atributo &#8216;perms&#8217;. Realmente son el mismo, pero para guardar coherencia con el estándar OAuth 2, le han cambiado el nombre a &#8216;scope&#8217;.</p>
</div>
<h2>Paso 2 &#8211; Conocer el SDK JavaScript</h2>
<p>Hasta ahora no hemos usado directamente el SDK de JavaScript. Únicamente lo hemos cargado indicándole algunos valores, como por ejemplo que renderice automáticamente todos los objetos XFBML (gracias a eso hemos podido incluir los Social Plugins).</p>
<p>Vamos a revisar algunos métodos que nos van a ser especialmente útiles para nuestra demo (recuerda que puedes consultar la documentación completa del SDK de JavaScript en <a href="http://developers.facebook.com/docs/reference/javascript/">http://developers.facebook.com/docs/reference/javascript/</a>):</p>
<h3><a href="http://developers.facebook.com/docs/reference/javascript/FB.api/">FB.api</a></h3>
<p>Este método es el que nos permitirá realizar consultas al <a href="http://developers.facebook.com/docs/api">Graph API</a>, que como vimos en la primera parte, es la herramienta donde todos los objetos de Facebook (personas, páginas, imágenes, etc.) están interconectados, y a la que podemos invocar para realizar consultas o modificaciones. Este método acepta 4 parámetros:</p>
<ol>
<li><strong>path</strong> - String con la ruta al API.</li>
<li><strong>method</strong> - Tipo de petición (GET, POST o DELETE).</li>
<li><strong>params</strong> - Objeto con los parámetros de la consulta (si los necesitara).</li>
<li><strong>cb</strong> - Función callback.</li>
</ol>
<p>Usualmente sólo serán necesarios <em>path</em> y <em>cb</em>.</p>
<h3><a href="http://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus/">FB.getLoginStatus</a></h3>
<p>Permite determinar si el usuario ha iniciado sesión y está conectado con nuestra aplicación. Acepta dos parámetros:</p>
<ol>
<li><strong>cb</strong> - Función callback con el parámetro &#8216;response&#8217;.</li>
<li><strong>force</strong> - Booleano que obligar a recargar el estado de login.</li>
</ol>
<p>Cuando se invoca a este método, se realiza una consulta HTTP que devuelve el objeto &#8216;response&#8217; de la función callback. Este objeto tiene la siguiente estructura:</p>
<pre name="code" class="javascript">{
    status: 'connected',
    authResponse: {
        accessToken: '...',
        expiresIn:'...',
        signedRequest:'...',
        userID:'...'
    }
}</pre>
<p>Si el objeto response contiene un objeto authResponse, sabremos con certeza que el usuario ha iniciado sesión y que está conectado a nuestra aplicación. Los campos accessToken y userID serán muy útiles para hacer llamadas a la API de Graph API. Pero no te preocupes por esto, ya que el SDK JavaScript se encarga de hacer todas las gestiones por nosotros como luego veremos sin necesidad de manejar nosotros esos parámetros <img src='http://chusete.es/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<h3><a href="http://developers.facebook.com/docs/reference/javascript/FB.getSession/">FB.getAuthResponse</a></h3>
<p>Su funcionamiento es equivalente al del método FB.getLoginStatus. La única diferencia es que, en lugar de devolver un objeto response, sólo devuelve su campo authResponse. Es decir, llamaremos a FP.getAuthResponse cuando tengamos la certeza de que el usuario ha iniciado sesión (y está conectado a nuestra aplicación) y queramos obtener información acerca de la sesión.</p>
<h3><a href="http://developers.facebook.com/docs/reference/javascript/FB.init/">FB.init</a></h3>
<p>Este es el único método que hemos invocado directamente hasta ahora. Se encarga de inicializar el SDK. Acepta un único parámetro, options, de tipo objeto, que incluye todas las propiedades que queramos establecer. En concreto, hemos usado estas propiedades (existen más):</p>
<ul>
<li><strong>appId</strong> &#8211; String con el ID público de nuestra aplicación.</li>
<li><strong>status</strong> &#8211; Booleano que indica si se debe o no comprobar el estado.</li>
<li><strong>cookie</strong> &#8211; Booleano que habilita o deshabilita el soporte para la cookie. Ésta podrá usarse posteriormente para que, desde el servidor, por ejemplo en PHP, se realicen peticiones al API.</li>
<li><strong>xfbml</strong> &#8211; Booleano que indica si se deben o no renderizar los objetos de tipo XFBML disponibles en la página. Gracias a esto, se han generado automáticamente hasta ahora los social plugins que hemos definido.</li>
<li><strong>channelURL</strong> &#8211; String con la URL del fichero channel.html. Usándolo se evitan algunos errores. Consulta la documentación de este método para saber más.</li>
<li><strong>oauth</strong> &#8211; Booleano que habilita o deshabilita soporte para OAuth 2.0. Tenlo siempre a true, pues muy pronto sólo se permitirá autenticación OAuth 2.0.</li>
</ul>
<h3><a href="http://developers.facebook.com/docs/reference/javascript/FB.login/">FB.login</a></h3>
<p>Este método se encarga de gestionar el login por nosotros. Es decir, renderiza el diálogo OAuth con los permisos necesarios, y gestiona la respuesta devuelta por éste. No lo vamos a invocar directamente, pero ten en cuenta que el Login Button por debajo utiliza este método.</p>
<p>Tan solo acepta dos parámetros:</p>
<ol>
<li><strong>cb</strong> - Función callback para gestionar la respuesta del usuario.</li>
<li><strong>opts</strong> - Objeto para modificar el comportamiento del login. Tan solo tiene una propiedad, &#8216;scope&#8217;, que como vimos más arriba acepta un string de los permisos que solicitamos, separados por coma.</li>
</ol>
<h3><a href="http://developers.facebook.com/docs/reference/javascript/FB.logout/">FB.logout</a></h3>
<p>Cierra la sesión del usuario. Sólo acepta un parámetro:</p>
<ol>
<li><strong>cb</strong> - Función callback para gestionar el cierre de sesión.</li>
</ol>
<h3><a href="http://developers.facebook.com/docs/reference/javascript/FB.ui/">FB.ui</a></h3>
<p>Es el responsable de renderizar por nosotros los diálogos. Ya lo hemos visto en funcionamiento cuando hemos pulsado el Login Button y se ha desplegado el diálogo OAuth. Pero, por supuesto, también podremos invocar a mano este método siempre que deseemos mostrar cualquier otro diálogo.</p>
<p>Acepta dos parámetros:</p>
<ol>
<li><strong>params</strong> - Objeto con todas las propiedades de configuración. Cada diálogo tiene sus propias propiedades (en la documentación de cada uno podrás conocerlas). Además, hay dos propiedades globales a todos los diálogos:</li>
<ol>
<li><strong>method</strong> - String con el nombre del diálogo que se desea mostrar. Obligatorio.</li>
<li><strong>display</strong> - String que indica la forma en que se mostrará el diálogo, por ejemplo &#8216;popup&#8217; . Opcional.</li>
</ol>
<li><strong>cb</strong> - Función callback para manejar la respuesta.</li>
</ol>
<h3><a href="http://developers.facebook.com/docs/reference/javascript/FB.Event.subscribe/">FB.Event.subscribe</a></h3>
<p>JavaScript es un lenguaje dirigido por eventos. Siguiendo este paradigma, el SDK JavaScript genera una serie de eventos a los que podemos suscribirnos para ejecutar una función callback. Este método acepta dos parámetros:</p>
<ol>
<li><strong>name</strong> &#8211; String con el nombre del evento al que nos queremos suscribir.</li>
<li><strong>fb</strong> &#8211; Función callback que se ejecutará cuando se dispare el evento.</li>
</ol>
<p>Entre los posibles eventos están <em>auth.login</em>, <em>auth.authResponseChange</em>, <em>auth.statusChange</em>, <em>auth.logout</em> además de otros muchos. Algunos de estos eventos generan un objeto que se pasará como parámetro a su función callback. Revisa la documentación para conocer más detalles.</p>
<p>Del mismo modo que nos podemos suscribir a un evento, también nos podemos desuscribir de él, mediante el método <a href="http://developers.facebook.com/docs/reference/javascript/FB.Event.unsubscribe/">FB.Event.unsubscribe</a>.</p>
<h3><a href="http://developers.facebook.com/docs/reference/javascript/FB.XFBML.parse/">FB.XFBML.parse</a></h3>
<p>Si bien en la demo no vamos a invocar este método, convine conocerlo, pues se ejecuta igualmente. En las propiedades de inicialización del SDK establecimos el valor <em>xfbml</em> a true. Esto significa que será el método FB.init el que llame a FB.XFBML.parse automáticamente por nosotros. Si no fuera así, lo podríamos invocar a mano con los siguientes parámetros:</p>
<ol>
<li><strong>dom</strong> &#8211; Elemento DOM raíz a partir del cual se parsearán todos sus hijos XFBML.</li>
<li><strong>cb</strong> &#8211; Función callback.</li>
</ol>
<h3>Resto de métodos</h3>
<p>Todavía quedan algunos métodos del SDK JavaScript. Dos de ellos (<a href="http://developers.facebook.com/docs/reference/javascript/FB.Data.query/">FB.Data.query</a> y <a href="http://developers.facebook.com/docs/reference/javascript/FB.Data.waitOn/">FB.Data.waitOn</a>) no los hemos visto, ya que quedarán obsoletos a partir del 1 de enero de 2012 (su comportamiento se puede llevar a cabo mediante FB.api). El resto de métodos tratan sobre canvas; es decir, para gestionar aspectos gráficos relacionados con el elemento iframe donde se ubican las aplicaciones que se empotran en la página de Facebook. Estos métodos sobre canvas los veremos en la siguiente parte.</p>
<h2>Paso 3 &#8211; Juntándolo todo</h2>
<p>Volviendo a nuestra demo, hemos visto que ésta ya nos permite autenticarnos. Pero esto por sí solo no es algo muy útil. Por eso ahora queremos que haga más cosas. En concreto:</p>
<ul>
<li>Queremos que cuando el usuario haya iniciado sesión, ya no se muestre el Login Button.</li>
<li>Cuando haya iniciado sesión, se mostrará un botón para cerrar sesión.</li>
<li>Además, consultaremos al Graph API algunos datos del usuario para mostrar su nombre y su avatar.</li>
<li>Añadiremos un botón que publicará automáticamente una historia en su muro.</li>
<li>Mostraremos un diálogo para invitar a nuestros amigos a usar la aplicación.</li>
<li>De paso, y por simplificar, vamos a eliminar el plugin Live Stream y el plugin del botón &#8220;Me gusta&#8221;.</li>
</ul>
<p>¿Parece mucho? Vas a ver qué sencillo es <img src='http://chusete.es/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Añadimos este código HTML:</p>
<pre name="code" class="html">    &lt;div id="user-box" style="text-align:center; display:none;"&gt;
        &lt;img id="image"/&gt;
        &lt;div id="name"&gt;&lt;/div&gt;
        &lt;a href="#" id="logout" onclick="userLogout()"&gt;Cerrar sesión&lt;/a&gt; &lt;br /&gt;
        &lt;a href="#" id="publish" onclick="publishStream()"&gt;Publicar en el muro&lt;/a&gt; &lt;br /&gt;
        &lt;a href="#" id="request" onclick="requestDialog()"&gt;Invitar a amigos&lt;/a&gt;
    &lt;/div&gt;</pre>
<p>Simplemente es un contenedor div, por defecto oculto, que mostrará una imagen, el nombre del usuario, y tres enlaces.</p>
<p>Vamos a por el nuevo código JavaScript que hemos añadido:</p>
<pre name="code" class="javascript">        FB.Event.subscribe('auth.login', function () {
            window.location.reload();
        });

        FB.Event.subscribe('auth.logout', function (response) {
            window.location.reload();
        });

        FB.getLoginStatus(function(response) {
            if (response.authResponse) {
                document.getElementById('fb-login-button').style.display = 'none';
                document.getElementById('user-box').style.display = 'block';
                FB.api('/me', function(user) {
                    if(user != null) {
                        var image = document.getElementById('image');
                        image.src = 'https://graph.facebook.com/' + user.id + '/picture';
                        var name = document.getElementById('name');
                        name.innerHTML = user.name
                    }
                });
            }
        });

        function userLogout() {
            FB.getLoginStatus(function(response) {
                if (response.authResponse) {
                    FB.logout();
                }
            });
        }

        function publishStream() {
            var body = 'Probando la demo del SDK de JavaScript de Facebook';
            FB.api('/me/feed', 'post', { message: body }, function(response) {
                if (!response || response.error) {
                    alert('Ha ocurrido un error');
                } else {
                    alert('¡Éxito! Entra a tu muro y verás una nueva publicación');
                }
            });
        }

        function requestDialog() {
            FB.ui({
                method: 'apprequests',
                message: 'Echa un vistazo a esta demo.',
                title: 'Compartir aplicación'
            });
        }</pre>
<p>Paso a paso:</p>
<ol>
<li>En primer lugar llamamos a <strong>FB.Event.subscribe</strong> para que cuando el usuario inicie sesión (es decir, cuando se lance el evento <em>auth.login</em>), la página se recargue.</li>
<li>Del mismo modo, cuando el usuario cierre sesión (cuando se lance el evento <em>auth.logout</em>), la página también se recargará.</li>
<li>Después invocamos a <strong>FB.getLoginStatus</strong>. Como vimos, con este método podemos saber si el usuario ha iniciado sesión y está conectado con nuestra aplicación, en función de si el objeto authResponse está o no presente. En ese caso de que lo esté (está conectado):</li>
<ol>
<li>Ocultamos el Login Button</li>
<li>Mostramos el div contenedor.</li>
<li>Realizamos una llamada a la API (<strong>FB.api</strong>) consultando información sobre el usuario activo. Construimos la URL de su avatar y lo establecemos a la imagen que hay dentro del div contenedor. E igualmente, extramos su nombre completo y lo escribimos en el div con id &#8216;name&#8217;.</li>
</ol>
<li>Ahora definimos la función userLogout() que se invoca al hacer clic sobre el texto &#8220;Cerrar sesión&#8221;. Comprobará si se ha iniciado sesión, y en caso afirmativo, la cierra (<strong>FB.logout</strong>).</li>
<li>La función publishStream se ejecuta cuando se hace clic sobre el texto &#8220;Publicar en el muro&#8221;. Mediante <strong>FB.api</strong>, realiza una llamada al método &#8216;/me/feed&#8217; del Graph API, usando una petición POST, y con el mensaje de &#8216;body&#8217;. Tras realizar la petición, se le notifica al usuario de si se ha publicado con éxito o no la historia.</li>
<li>Por último, definimos la función requestDialog, que se invoca al hacer clic sobre &#8220;Invitar a amigos&#8221;. Esta función realiza una llamada a <strong>FB.ui</strong>, pasándole tres parámetros (nombre del diálogo, texto de la petición, título de la petición), y genera el diálogo Request que permite enviar una invitación a los amigos para que usen la aplicación.</li>
</ol>
<p><a href="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-17-a-las-04.55.22.png"><img class="aligncenter size-medium wp-image-1165" title="Captura de pantalla 2011-09-17 a la(s) 04.55.22" src="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-17-a-las-04.55.22-300x65.png" alt="" width="300" height="65" /></a><a href="http://chusete.es/facebook/step2_2.html">Ver demo completa</a>.</p>
<h2>Resumen</h2>
<p>Hasta ahora ya conocíamos por encima todo el ecosistema de tecnologías para desarrollar en Facebook, y habíamos creado una primera aplicación que hacía uso de algunos Social Plugins y de Open Graph.</p>
<p>Esta vez ya nos hemos ensuciado más las manos. Hemos instanciado un nuevo Social Plugin (el <strong>Login Button</strong>), que nos ha generado el <strong>diálogo OAuth</strong>, con el que hemos podido solicitar determinados <strong>permisos</strong> para nuestra aplicación. Después hemos revisado los principales <strong>métodos del SDK JavaScript</strong>, y hemos visto cómo muchos de esos métodos ya estaban funcionando incluso sin invocarlos nosotros a manos. Después hemos puesto en práctica nuestro conocimiento del SDK: nos hemos atado a <strong>eventos</strong> generados por Facebook (<em>auth.login</em> y <em>auth.logout</em>), permitimos mostrar diferente contenido en función de si se ha iniciado o no sesión, <strong>consultamos en la API</strong> y mostramos información básica del usuario, hemos visto cómo <strong>cerrar sesión</strong>, cómo <strong>publicar en el muro del usuario</strong> directamente, y hemos creado un <strong>diálogo Request</strong> para invitar a nuestros amigos a usar la aplicación.</p>
<p>No está mal, ¿no? Con lo que ya conocemos, y un poco de imaginación, podemos crear aplicaciones muy ricas en funcionalidades. Pero todavía nos quedan algunas cosas por ver en esta serie introductoria a la programación en Facebook: cómo crear aplicaciones canvas, y cómo manejar el PHP SDK. Nos vemos en la siguiente parte y, como siempre, ¡gracias por leer!
<div class="tweetmeme_button" style="float: left; margin-right: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fchusete.es%2F2011%2F09%2F18%2Fintroduccion-a-la-programacion-en-facebook-iii%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fchusete.es%2F2011%2F09%2F18%2Fintroduccion-a-la-programacion-en-facebook-iii%2F&amp;source=chuso&amp;style=normal&amp;service=bit.ly&amp;service_api=R_86054639b9f90148987197dfdc061697&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
]]></content:encoded>
			<wfw:commentRss>http://chusete.es/2011/09/18/introduccion-a-la-programacion-en-facebook-iii/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Introducción a la programación Facebook II</title>
		<link>http://chusete.es/2011/09/16/introduccion-a-la-programacion-facebook-ii/</link>
		<comments>http://chusete.es/2011/09/16/introduccion-a-la-programacion-facebook-ii/#comments</comments>
		<pubDate>Fri, 16 Sep 2011 08:00:37 +0000</pubDate>
		<dc:creator>chusete</dc:creator>
				<category><![CDATA[desarrollo]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[javasctipt]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[facebook API]]></category>
		<category><![CDATA[insights]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[xfbml]]></category>

		<guid isPermaLink="false">http://chusete.es/?p=1139</guid>
		<description><![CDATA[Ok, el anterior artículo no estuvo mal; vimos una introducción conceptual a las piezas clave para la construcción de aplicaciones en Facebook. ¡Pero no llegamos a hacer nada! En este post vamos a construir algo sencillo, jugando con el SDK en JavaScript. Vamos a probar a mostrar algunos de los social plugins, usaremos Open Graph, y presentaremos [...]]]></description>
			<content:encoded><![CDATA[<p><img class="aligncenter size-full wp-image-1147" title="banner_fb2" src="http://chusete.es/wp-content/uploads/2011/09/banner_fb2.jpg" alt="" width="100%" /></p>
<p>Ok, el <a href="/2011/09/13/introduccion-a-la-programacion-en-facebook/">anterior artículo</a> no estuvo mal; vimos una introducción conceptual a las piezas clave para la construcción de aplicaciones en Facebook. ¡Pero no llegamos a hacer nada! En este post vamos a construir algo sencillo, jugando con el SDK en JavaScript. Vamos a probar a mostrar algunos de los social plugins, usaremos Open Graph, y presentaremos dos nuevas tecnologías: XFBML y Facebook Insights. ¡Al lío!</p>
<p><span id="more-1139"></span></p>
<h2>Paso 1 &#8211; Alojamiento para la aplicación</h2>
<p>Es responsabilidad del desarrollador buscar un alojamiento para su aplicación. Esto no suele ser un problema, ya que sirve cualquiera al que tengas acceso FTP. Sin embargo, desde el 1 de octubre de 2011 Facebook obliga a que las aplicaciones estén disponibles tanto por HTTP como por HTTPS.</p>
<p>Por lo pronto vamos a crear una carpeta llamada &#8220;/facebook&#8221; en el directorio raíz de la web, que será desde donde se acceda a nuestra aplicación.</p>
<div class="note">
<h3>Alojamiento gratuíto</h3>
<p>Desde el 15 de septiembre de 2011, Facebook ha llegado a un acuerdo con la compañía Heroku para ofrecer gratis un alojamiento reducido pero funcional para todo el que lo solicite. Queda fuera del alcance de esta guía explicar cómo utilizar este servicio. <a href="https://developers.facebook.com/blog/post/558/">Más información</a>.</p>
</div>
<h2>Paso 2 &#8211; Configurando la aplicación</h2>
<p>Ahora, accedemos a <a href="https://developers.facebook.com/">developers.facebook.com</a>, y de ahí vamos a la pestaña Aplicaciones. Seleccionamos la nuestra, y en el apartado de configuración pinchamos en &#8220;<em>Edit settings</em>&#8220;. En la parte inferior, tal como vimos en el anterior artículo, nos dan cuatro opciones para crear nuestra aplicación. Vamos a seleccionar Website e introducimos la URL completa con la que se accederá a nuestra aplicación. En mi caso, introduzco <a href="http://chusete.es/facebook">http://chusete.es/facebook</a>.</p>
<p><a href="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-16-a-las-06.03.58.png"><img class="aligncenter size-medium wp-image-1150" title="Captura de pantalla 2011-09-16 a la(s) 06.03.58" src="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-16-a-las-06.03.58-300x29.png" alt="" width="300" height="29" /></a></p>
<p>Pulsamos en <em>Guardar cambios</em>, y ya está. Ésta ha sido fácil <img src='http://chusete.es/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2>Paso 3 &#8211; Creando el esqueleto</h2>
<p>Ahora, en la carpeta /facebook de nuestro alojamiento web, vamos a crear un fichero llamado index.html con la estructura básica de un documento HTML. Además, añadiremos el código JavaScript que vimos en el anterior artículo que había que insertar para usar el SDK. Quedaría así el esqueleto:</p>
<pre name="code" class="html">&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8" /&gt;
    &lt;title&gt;Demo Facebook&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;Demo Facebook&lt;/h1&gt;

    &lt;div id="fb-root"&gt;&lt;/div&gt;
    &lt;script type="text/javascript" src="http://connect.facebook.net/es_ES/all.js"&gt;&lt;/script&gt;
    &lt;script type="text/javascript"&gt;
        FB.init({
            appId  : '256797284360192',
            status : true, // comprobar estado de login
            cookie : true, // habilitar cookies para permitir al servidor acceder a la sesión
            xfbml  : true, // renderizar código XFBML
            channelURL : 'http://chusete.es/facebook/channel.html', // fichero channel.html
            oauth  : true // habilita OAuth 2.0
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
<div class="note">
<h3>Acerca de channelURL</h3>
<p>Si te fijas, verás que en la línea 18 hay una URL que apunta a channelURL. Este fichero tan sólo tendrá este contenido:</p>
<pre name="code" class="html">&lt;script src="http://connect.facebook.net/es_ES/all.js"&gt;&lt;/script&gt;</pre>
<p>Para saber más acerca de por qué es recomendable crear el fichero channel.html, consulta la documentación de la función <a href="https://developers.facebook.com/docs/reference/javascript/FB.init/">FB.init</a>.</p>
</div>
<p>Llegados a este punto, ya tenemos listo el esqueleto sobre el que construir una pequeña aplicación de demo. <a href="http://chusete.es/facebook/step3.html">Ver resultado del paso 3</a>.</p>
<h2>Paso 4 &#8211; Añadiendo Social Plugins (XFBML)</h2>
<p>Ya vimos que hay, ni más ni menos, que 10 social plugins. Vamos a insertar algunos a nuestra aplicación. Pero antes un poco de teoría. Hace tiempo, Facebook creó su propio lenguaje de marcado para poder insertar social plugins en nuestras aplicaciones. Hablamos del FBML (Facebook Markup Language). Para que pudierar interactuar con JavaScript, crearon FBJS; un dialecto de JavaScript para usarlo en conjunto con FBML dentro del espacio de Facebook. Sin embargo, desde el 11 de marzo de 2011, todo <a href="http://developers.facebook.com/blog/post/462">este conjunto de tecnologías ha quedado fuera de uso</a>. ¿Y qué hay en su lugar? Pues un sistema unificado para todas las aplicaciones, ya sean pestañas, aplicaciones en canvas, externas, etc., basado en tecnologías estándar: HTML, CSS y JavaScript. Mucho mejor, ¿verdad?</p>
<p>Para sustituir a FBML crearon XFBML, que es un sistema que, mediante etiquetas HTML estándar, permite definir Social Plugins. Por ejemplo, el botón &#8220;Me gusta&#8221; es algo tan sencillo como:</p>
<pre name="code" class="html">&lt;div data-send="false" data-width="450" data-show-faces="false"&gt;&lt;/div&gt;</pre>
<p>¿Cómo se hace para que ese código HTML se renderice como el Social Plugin &#8220;Me gusta&#8221;? Hay dos opciones:</p>
<ol>
<li>Si en el código de inicialización del SDK JavaScript (el método FB.init que hemos invocado en index.html) tenemos a true el campo xfbml, entonces se renderizarán todas las etiquetas XFBML automáticamente.</li>
<li>En caso contrario, podremos renderizarlas invocando a <a href="http://developers.facebook.com/docs/reference/javascript/FB.XFBML.parse/">FB.XFBML.parse</a>.</li>
</ol>
<p>Vale, ahora sólo nos queda saber cómo averiguar el código HTML que define cada Social Plugin. Accede a la página de <a href="http://developers.facebook.com/docs/plugins/">Social Plugins</a>, elige el que quieras usar, completa el formulario con los valores que desees (si es que el plugin te da esa opción), y finalmente pulsa sobre el botón <em>Get Code</em>. ¡Pero ojo! El código que te genera incluye tanto la inicialización del SDK, como el código HTML que define el plugin. Como nosotros ya tenemos el código del SDK, sólo tendremos que copiar el código HTML del plugin.</p>
<p>Por ejemplo, vamos a insertar un plugin <a href="http://developers.facebook.com/docs/reference/plugins/live-stream/">Live Stream</a> en nuestra demo. Al pulsar en <em>Get Code</em> obtenemos lo siguiente:</p>
<p><a href="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-16-a-las-04.04.58.png"><img class="aligncenter size-medium wp-image-1140" title="Captura de pantalla 2011-09-16 a la(s) 04.04.58" src="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-16-a-las-04.04.58-300x179.png" alt="" width="300" height="179" /></a></p>
<p>Copiamos sólo el código HTML:</p>
<pre name="code" class="html">&lt;div data-event-app-id="282078738484719" data-width="400" data-height="500" data-always-post-to-friends="false"&gt;&lt;/div&gt;</pre>
<p>Con lo que ya tendríamos un chat en nuestra aplicación web, con el siguiente aspecto:</p>
<p><a href="http://chusete.es/facebook/step4.html"><img class="aligncenter size-full wp-image-1141" title="Captura de pantalla 2011-09-16 a la(s) 04.17.38" src="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-16-a-las-04.17.38.png" alt="" width="430" height="594" /></a></p>
<p><a href="http://chusete.es/facebook/step4.html">Ver resultado del paso 4</a>.</p>
<h2>Paso 5 &#8211; Botón &#8220;Me gusta&#8221; y Open Graph</h2>
<p>Del mismo modo que hemos insertado un plugin Live Stream, ahora vamos a insertar el famoso botón &#8220;Me gusta&#8221;. Como vimos, para obtener el código XFBML debemos acceder a la página del plugin, completar el formulario, obtenemos su código, y lo copiamos. Siguiendo esos pasos obtendrás algo similar a esto (en función de cómo complementes el formulario):</p>
<pre name="code" class="html">&lt;div data-send="false" data-width="450" data-show-faces="false"&gt;&lt;/div&gt;</pre>
<p>Con solo pegar ese código al documento HTML, ya tendremos el botón en nuestra página. ¡Pero un momento! Como vimos en la primera parte, existe una tecnología llamada Open Graph que convierte un documento web en todo un objeto social, referenciable y al que como administradores podemos seguirle el rastro. Pues bien, vamos a hacer esto. En la propia página del plugin del botón &#8220;Me gusta&#8221; tenemos un formulario que nos permite generar algunos códigos Open Graph -aunque generarlos a mano es algo trivial. En mi caso, lo he dejado así:</p>
<pre name="code" class="html">&lt;meta property="og:title" content="Página demo de Facebook" /&gt;
&lt;meta property="og:type" content="website" /&gt;
&lt;meta property="og:description" content="Ésta es la página de demo de la segunda parte de la introducción a programación en Facebook de chusete.es" /&gt;
&lt;meta property="og:url" content="http://chusete.es/facebook/index.html" /&gt;
&lt;meta property="og:image" content="http://chusete.es/facebook/logo.png" /&gt;
&lt;meta property="og:site_name" content="chuso!" /&gt;
&lt;meta property="fb:admins" content="1048522537" /&gt;</pre>
<p>Ahora, cuando alguien comparta esta página en Facebook, ésa será la información que se mostrará por defecto. Por ejemplo, en este caso quedaría así:</p>
<p><a href="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-16-a-las-04.45.32.png"><img class="aligncenter size-medium wp-image-1142" title="Captura de pantalla 2011-09-16 a la(s) 04.45.32" src="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-16-a-las-04.45.32-300x154.png" alt="" width="300" height="154" /></a></p>
<p><a href="chusete.es/facebook/index.html">Ver resultado final</a>.</p>
<h2>Paso 6 &#8211; Página para administradores e Insights</h2>
<p>Pero hay más. Junto con la información Open Graph hemos insertado una etiqueta más, en la que el atributo property tiene como valor &#8220;fb:admins&#8221;. Ese campo contiene el id de nuestro usuario, de manera que así constaremos como el propietario de la página. ¿De qué nos sirve esto? Pues en resumen, para dos cosas. Fíjate en cómo queda el botón &#8220;Me gusta&#8221; cuando <strong>tú</strong> lo visualizas:</p>
<p><img class="aligncenter size-full wp-image-1143" title="Captura de pantalla 2011-09-16 a la(s) 05.14.40" src="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-16-a-las-05.14.40.png" alt="" width="416" height="40" /><br />
Interesante&#8230; Hay un link a &#8220;Página para administradores&#8221; y a &#8220;Estadísticas&#8221;. ¿Qué son?</p>
<h3>Página para administradores</h3>
<p>Cuando alguien pulse sobre el botón &#8220;Me gusta&#8221;, se creará un nuevo panel de administración con el que podrás comunicarte con tus &#8220;likers&#8221; (aquellos a los que les ha gustado tu publicación). Este panel estará disponible desde tu <a href="http://www.facebook.com/bookmarks/pages">lista de Facebook Pages</a>. Y lo más interesante: todo lo que publiques en el muro de esta página, aparecerá en las lista de novedades de los usuarios a los que les gustó tu publicación.</p>
<p><a href="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-16-a-las-05.17.26.png"><img class="aligncenter size-medium wp-image-1144" title="Captura de pantalla 2011-09-16 a la(s) 05.17.26" src="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-16-a-las-05.17.26-300x190.png" alt="" width="300" height="190" /></a></p>
<h3>Insights</h3>
<p>Y en segundo lugar, tendrás acceso a las estadísticas en <a href="www.facebook.com/insights/">Facebook Insights</a> (¡otra más de las tecnologías de Facebook!). Básicamente, es un panel de análisis de tráfico web, similar a Google Analytics. Puedes acceder desde el enlace &#8220;Estadísticas&#8221; que acompaña al botón &#8220;Me gusta&#8221;, pero es preferible reclamar la propiedad de tu dominio ante Facebook, para de ese modo tener acceso completo a todo lo que ocurre con tu página. Para ello, accedemos a la página principal de Insights, y pulsamos sobre el botón <img class="alignnone size-full wp-image-1145" title="Captura de pantalla 2011-09-16 a la(s) 05.25.00" src="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-16-a-las-05.25.00.png" alt="" width="172" height="25" />. Mete el dominio de tu web, copia el código &#8220;meta&#8221; que te ha generado, y pégalo en la página principal del dominio:</p>
<p><a href="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-16-a-las-05.25.56.png"><img class="aligncenter size-medium wp-image-1146" title="Captura de pantalla 2011-09-16 a la(s) 05.25.56" src="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-16-a-las-05.25.56-300x237.png" alt="" width="300" height="237" /></a>Finalmente pulsa en Get Insights y ya habrá finalizado el proceso de alta en Facebook Insights. Ahora, cada vez que accedas al dashboard de Insights, podrás consultar qué historias de tu página se han compartido o han gustado en Facebook.</p>
<p>Para más información, consulta la documentación de <a href="http://developers.facebook.com/docs/insights/">Facebook Insights</a>.</p>
<h2>Resumen</h2>
<p>En la primera parte dimos un repaso a las principales tecnologías que involucran el desarrollo de aplicaciones Facebook, y dimos de alta un nuevo perfil de aplicación.</p>
<p>Hoy, hemos visto cómo crear una aplicación en una web externa a Facebook vinculada a nuestro alojamiento. Hemos creado un documento HTML con el código de incialización del SDK JavaScript. Hemos conocido una tecnología de Facebook -XFBML- que nos permite crear plugins de una forma muy sencilla. Como ejemplo, hemos creado un plugin de tipo Live Stream, y otro con el botón &#8220;Me gusta&#8221;. También hemos añadido los códigos Open Graph y hemos visto su utilidad. Finalmente, hemos visto cómo interactuar con los usuarios a los que les gustan nuestras publicaciones, y cómo explorar las estadísticas de uso de nuestro sitio por los usuarios de Facebook.</p>
<p>&nbsp;
<div class="tweetmeme_button" style="float: left; margin-right: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fchusete.es%2F2011%2F09%2F16%2Fintroduccion-a-la-programacion-facebook-ii%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fchusete.es%2F2011%2F09%2F16%2Fintroduccion-a-la-programacion-facebook-ii%2F&amp;source=chuso&amp;style=normal&amp;service=bit.ly&amp;service_api=R_86054639b9f90148987197dfdc061697&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
]]></content:encoded>
			<wfw:commentRss>http://chusete.es/2011/09/16/introduccion-a-la-programacion-facebook-ii/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Introducción a la programación en Facebook</title>
		<link>http://chusete.es/2011/09/13/introduccion-a-la-programacion-en-facebook/</link>
		<comments>http://chusete.es/2011/09/13/introduccion-a-la-programacion-en-facebook/#comments</comments>
		<pubDate>Tue, 13 Sep 2011 00:09:47 +0000</pubDate>
		<dc:creator>chusete</dc:creator>
				<category><![CDATA[desarrollo]]></category>
		<category><![CDATA[javasctipt]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[API Graph]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[facebook API]]></category>
		<category><![CDATA[open graph]]></category>

		<guid isPermaLink="false">http://chusete.es/?p=1091</guid>
		<description><![CDATA[¿De modo que te han pedido que hagas una aplicación para Facebook y no sabes por dónde empezar? ¿Has llegado a la documentación oficial y te pierdes entre tanto Open Graph, SDK, plugins, dialogs y Graph API? Don&#8217;t panic! En este artículo vamos a ver paso a paso cómo empezar a programar en el nuevo sistema [...]]]></description>
			<content:encoded><![CDATA[<p><img class="aligncenter size-full wp-image-1129" title="head_fb1" src="http://chusete.es/wp-content/uploads/2011/09/head_fb1.jpg" alt="" width="100%" /></p>
<p>¿De modo que te han pedido que hagas una aplicación para Facebook y no sabes por dónde empezar? ¿Has llegado a la <a href="https://developers.facebook.com/docs/">documentación oficial</a> y te pierdes entre tanto Open Graph, SDK, plugins, dialogs y Graph API? Don&#8217;t panic! En este artículo vamos a ver paso a paso cómo empezar a programar en el nuevo sistema de Facebook. ¡Al lío!</p>
<p><span id="more-1091"></span></p>
<h2>Tipos de aplicaciones</h2>
<p>En el apartado <em><a href="http://developers.facebook.com/docs/">Getting Started</a></em> de la documentación oficial vemos que nos dan tres opciones:</p>
<ol>
<li><strong><a href="https://developers.facebook.com/docs/guides/web/">Páginas web</a></strong>. Para crear una aplicación que se ejecute en tu página web fuera de Facebook.</li>
<li><strong><a href="https://developers.facebook.com/docs/guides/mobile/">Aplicaciones móviles</a></strong>. Para crear apps para las principales infraestructuras móviles.</li>
<li><strong><a href="https://developers.facebook.com/docs/guides/canvas/">Aplicaciones en Facebook</a></strong>. Este decir, para crear una aplicación que se insertará dentro de la web de Facebook, en un <strong>canvas</strong>.</li>
</ol>
<p>En cualquiera de los tres casos, las tecnologías que utilizaremos serían básicamente las mismas.</p>
<p>Más adelante revisaremos algunas de las tecnologías que nos ofrece Facebook para integrar nuestra aplicación con su infraestructura.</p>
<div class="note">
<h3>Aplicaciones de Escritorio</h3>
<p>Existe un cuarto tipo de aplicaciones, que no se mencionan, y que pueden comunicarse con Facebook: Aplicaciones de escritorio. En esta guía no lo abordaremos.</p>
</div>
<p>Además, en la página de inicio ofrecen un <a href="https://developers.facebook.com/docs/samples/">apartado de ejemplos</a> donde podrás probar y descargar distintas demos, como el de una aplicación en página web, o una aplicación dentro de un canvas en Facebook. También puedes acceder a <a href="https://developers.facebook.com/videos/">vídeos</a> con charlas y guías.</p>
<h2>Dando de alta una aplicación</h2>
<p>Para entender mejor todos los apartados, y para poder realizar algunos ejemplos, vamos a crearnos una nueva aplicación. Para ello, vamos a seguir los siguientes pasos:</p>
<p>Accedemos a la página de desarrolladores de Facebook: <a href="https://developers.facebook.com/">https://developers.facebook.com/</a></p>
<p><a href="https://developers.facebook.com/"></a>Una vez ahí, seleccionamos &#8220;<a href="https://developers.facebook.com/apps">Aplicaciones</a>&#8221; en el menú.</p>
<p>En tercer lugar, pulsamos sobre el botón <a href="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-12-a-las-23.10.39.png"><img class="alignnone size-full wp-image-1110" title="Captura de pantalla 2011-09-12 a la(s) 23.10.39" src="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-12-a-las-23.10.39.png" alt="" width="120" height="24" /></a>.</p>
<p>Ahora indicamos un nombre y la local de la aplicación y pulsamos <em>Continuar</em>:</p>
<p><a href="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-12-a-las-23.11.27.png"><img class="aligncenter size-medium wp-image-1111" title="Captura de pantalla 2011-09-12 a la(s) 23.11.27" src="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-12-a-las-23.11.27-300x109.png" alt="" width="300" height="109" /></a></p>
<p>Completamos el captcha y pulsamos sobre <em>Enviar:</em></p>
<p><em><a href="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-12-a-las-23.12.48.png"><img class="aligncenter size-medium wp-image-1112" title="Captura de pantalla 2011-09-12 a la(s) 23.12.48" src="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-12-a-las-23.12.48-300x127.png" alt="" width="300" height="127" /></a></em></p>
<p>Y con esto ya estaría dada de alta nuestra aplicación:</p>
<p><a href="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-12-a-las-23.14.33.png"><img class="aligncenter size-medium wp-image-1113" title="Captura de pantalla 2011-09-12 a la(s) 23.14.33" src="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-12-a-las-23.14.33-300x252.png" alt="" width="300" height="252" /></a></p>
<p>Fíjate en la caja superior. Verás dos campos: App ID y App Secret. Estos código los necesitarás para hacer funcionar tu aplicación. El primero es el código que identifica la app, y el segundo es un código de seguridad que utilizarás para la autenticación en el lado del servidor.</p>
<p>Por lo pronto, podemos cambiar los siguientes campos:</p>
<ul>
<li><strong>Logo</strong>. Corresponde al logo de 75&#215;75 px de la aplicación.</li>
<li><strong>Icono</strong>. Icono de 16&#215;16 px de la aplicación</li>
<li><strong>App Secret</strong>. Este código no debemos compartirlo con nadie. Desde este apartado podremos reiniciarlo si lo deseáramos.</li>
<li><strong>App Display Name.</strong> Nombre con el que se mostrará la aplicación.</li>
<li><strong>App Namespace.</strong> Nombre del espacio de nombres de la aplicación, formado únicamente por caracteres en minúsculas, guiones medios y guiones bajos.</li>
<li><strong>Contact Email.</strong> Dirección de correo electrónico de contacto.</li>
<li><strong>App Domain.</strong> Dominio sobre el que se alojará la aplicación (por ejemplo www.example.com).</li>
<li><strong>Category</strong> y <strong>Sub-category.</strong> Categorías en las que catalogamos la aplicación.</li>
</ul>
<p>Además, vemos que podemos definir 4 formas distintas de integrar la aplicación con Facebook:</p>
<ol>
<li><strong>Website.</strong> Para cuando queramos que en nuestra página puedan los usuarios hacer login con su cuenta de Facebook.</li>
<li><strong>App on Facebook.</strong> Aplicación para incorporar en un canvas dentro de Facebook.</li>
<li><strong>Mobile Native.</strong> Para crear una aplicación para móviles.</li>
<li><strong>Page Tab.</strong> Permite crear una aplicación que se mostrará como una pestaña dentro de una Facebook Page.</li>
</ol>
<p>Y estas son todas las opciones básicas que tenemos disponibles para configurar una aplicación de Facebook. Sin embargo, podemos acceder a la configuración avanzada desde el menú de la izquierda, pulsando sobre <em>Configuration &gt; Advanced</em>:</p>
<p><a href="http://chusete.es/wp-content/uploads/2011/09/Advanced-Desarrolladores-de-Facebook.png"><img class="aligncenter size-medium wp-image-1114" title="Advanced - Desarrolladores de Facebook" src="http://chusete.es/wp-content/uploads/2011/09/Advanced-Desarrolladores-de-Facebook-188x300.png" alt="" width="188" height="300" /></a></p>
<p>En este apartado avanzado por ahora podremos establecer la descripción de nuestra aplicación, y el <em>Sandbox Mode</em> (habilitado indica que sólo los desarrolladores pueden acceder a la aplicación).</p>
<p>Rápido e indoloro, ya tenemos nuestra aplicación creada <img src='http://chusete.es/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Cada vez que queramos volver a la configuración de nuestra aplicación, tan solo tendremos que acceder a la página de desarrolladores de Facebook, apartado <a href="https://developers.facebook.com/apps">Aplicaciones</a>, y seleccionamos la opción deseada.</p>
<div class="note">
<h3>Página dentro de Facebook</h3>
<p>Si quisiéramos acceder a la página de la aplicación (su página dentro de Facebook, no su perfil de configuración), desde su pantalla de configuración, en el menú izquierda, pulsamos sobre <em>View App Profile Page</em>. Veremos una página en blanco esperando a ser completada:</p>
<p style="text-align: center;"><a href="http://chusete.es/wp-content/uploads/2011/09/chusete-demo.png"><img class="size-medium wp-image-1117 aligncenter" title="chusete demo" src="http://chusete.es/wp-content/uploads/2011/09/chusete-demo-192x300.png" alt="" width="192" height="300" /></a></p>
<p style="text-align: left;">Podremos completar la página de perfil de la aplicación en cualquier momento.</p>
</div>
<h2>Tecnologías disponibles</h2>
<p>Bien, y ¿qué tecnologías nos ofrece Facebook para implementar una aplicación? Éstas son las principales:</p>
<h3>1. <a href="https://developers.facebook.com/docs/plugins/">Social plugins</a></h3>
<p>Corresponde a pequeños plugins o <em>widgets</em> que se pueden incorporar muy fácilmente en cualquier página web ajena a Facebook. Accediendo a la página de cada uno de ellos verás un pequeño formulario que te genera el código necesario para que lo incorpores en tu página. Seguro que estás muy familiarizado con casi todos ellos:</p>
<div style="overflow: hidden; margin-top: 10px;"><img class="alignleft size-full wp-image-1093" style="margin-right: 10px;" title="like" src="http://chusete.es/wp-content/uploads/2011/09/like.png" alt="" width="128" height="88" /><strong><a href="https://developers.facebook.com/docs/reference/plugins/like">Botón &#8220;Me gusta&#8221;.</a></strong><br />
Es el más famoso de todos los plugins. Permite a los usuarios compartir con un solo clic la página que están visitando</div>
<div style="overflow: hidden; margin-top: 10px;"><img class="alignleft size-full wp-image-1094" style="margin-right: 10px;" title="send" src="http://chusete.es/wp-content/uploads/2011/09/send.png" alt="" width="128" height="88" /><strong><a href="https://developers.facebook.com/docs/reference/plugins/send">Botón &#8220;Enviar&#8221;.</a></strong><br />
Permite que los usuarios envíen a alguno/s de sus contactos la página que están visitando.</div>
<div style="overflow: hidden; margin-top: 10px;"><img class="alignleft size-full wp-image-1095" style="margin-right: 10px;" title="comments" src="http://chusete.es/wp-content/uploads/2011/09/comments-1.png" alt="" width="128" height="88" /><strong><a href="https://developers.facebook.com/docs/reference/plugins/comments"> Comentarios.</a></strong><br />
Para añadir un sistema de comentarios a tu página web.</div>
<div style="overflow: hidden; margin-top: 10px;"><img class="alignleft size-full wp-image-1096" style="margin-right: 10px;" title="activityfeed" src="http://chusete.es/wp-content/uploads/2011/09/activityfeed.png" alt="" width="128" height="88" /><strong><a href="https://developers.facebook.com/docs/reference/plugins/activity">Feed de actividades.</a></strong><br />
Muestra una lista de las últimas actividades que han llevado a cabo tus contactos de Facebook.</div>
<div style="overflow: hidden; margin-top: 10px;"><img class="alignleft size-full wp-image-1097" style="margin-right: 10px;" title="recommendations" src="http://chusete.es/wp-content/uploads/2011/09/recommendations.png" alt="" width="128" height="88" /><strong><a href="https://developers.facebook.com/docs/reference/plugins/recommendations">Recomendaciones.</a></strong><br />
Muestra al usuario una lista personalizada de enlaces recomendados, en función de diferentes parámetros, como por ejemplo las preferencias de sus amigos.</div>
<div style="overflow: hidden; margin-top: 10px;"><img class="alignleft size-full wp-image-1098" style="margin-right: 10px;" title="likebox" src="http://chusete.es/wp-content/uploads/2011/09/likebox.png" alt="" width="128" height="88" /><strong><a href="https://developers.facebook.com/docs/reference/plugins/like-box">Caja &#8220;me gusta&#8221;.</a></strong><br />
Similar al botón &#8220;Me gusta&#8221;, pero con más elementos. Por ejemplo, muestra las últimas actividades de la página, o una lista de personas a las que les gusta.</div>
<div style="overflow: hidden; margin-top: 10px;"><img class="alignleft size-full wp-image-1099" style="margin-right: 10px;" title="login" src="http://chusete.es/wp-content/uploads/2011/09/login.png" alt="" width="128" height="88" /><strong><a href="https://developers.facebook.com/docs/reference/plugins/login">Botón &#8220;Login&#8221;.</a></strong><br />
Botón que permite iniciar sesión en la página utilizando la infraestructura de sesiones de Facebook.</div>
<div style="overflow: hidden; margin-top: 10px;"><img class="alignleft size-full wp-image-1100" style="margin-right: 10px;" title="register" src="http://chusete.es/wp-content/uploads/2011/09/register.png" alt="" width="128" height="88" /><strong><a href="https://developers.facebook.com/docs/plugins/registration">Registro.</a></strong><br />
Formulario de registro a una página que se rellena automáticamente con tus datos de Facebook. De este modo, se ahorra tiempo a los usuarios.</div>
<div style="overflow: hidden; margin-top: 10px;"><img class="alignleft size-full wp-image-1101" style="margin-right: 10px;" title="facepile" src="http://chusete.es/wp-content/uploads/2011/09/facepile.png" alt="" width="128" height="88" /><strong><a href="https://developers.facebook.com/docs/reference/plugins/facepile">Facepile.</a></strong><br />
Muestra una lista de imágenes de perfil de los usuarios a los que les ha gustado la página que se está visitando.</div>
<div style="overflow: hidden; margin-top: 10px;"><img class="alignleft size-full wp-image-1102" style="margin-right: 10px;" title="livestream" src="http://chusete.es/wp-content/uploads/2011/09/livestream.png" alt="" width="128" height="88" /><strong><a href="https://developers.facebook.com/docs/reference/plugins/live-stream">Live Stream.</a></strong><br />
Muestra un pequeño &#8216;chat&#8217; vinculado a la página que se está visitando.</div>
<p>Como ves, a base de insertar este tipo de plugins, puedes crear una página web muy rica en funcionalidades en un tiempo récord. A modo de demostración, <a href="http://www.myfbse.com/winery/storybar.html">puedes consultar esta página</a>, que forma parte del apartado de ejemplos de Facebook. Esta demo hace uso del <em>botón &#8220;me gusta&#8221;</em>, del <em>feed de actividades</em>, de las <em>recomendaciones</em> y de los <em>comentarios</em>.</p>
<h3>2. <a href="https://developers.facebook.com/docs/reference/dialogs/">Diálogos</a></h3>
<p>Podemos definir los diálogos como ventanas emergentes que solicitan al usuario permiso para realizar alguna acción.</p>
<div class="note"><strong>Autorizaciones</strong><br />
Más adelante veremos que si, por ejemplo, quisiéramos que nuestra aplicación publicara una entrada en el muro de un usuario, necesitaríamos que éste nos hubiera concedido previamente permisos para realizar esta acción. Con los diálogos esto no es necesario, ya que por definición un diálogo necesita que el usuario lo autorice para realizar cualquier acción.</div>
<p>Podemos invocar los diálogos a mano, sin embargo en general suele ser mucho más cómo realizarlo mediante alguno de los SDK que Facebook nos ofrece. En concreto, para páginas web, utilizaremos el <a href="https://developers.facebook.com/docs/reference/javascript/">SDK JavaScript</a> mediante el método <a href="https://developers.facebook.com/docs/reference/javascript/FB.ui">FB.ui</a>. En el apartado del SDK de JavaScript veremos cómo invocar estos diálogos.</p>
<p>Por lo pronto, vamos a ver cuáles son los distintos diálogos que nos ofrece Facebook:</p>
<p><strong>Diálogo de Feed</strong></p>
<p>Permite al usuario añadir a su muro, desde nuestra aplicación, una publicación.</p>
<p><a href="http://chusete.es/wp-content/uploads/2011/09/Facebook_Dialogs_Feed_Iframe.png"><img class="aligncenter size-medium wp-image-1104" title="Facebook_Dialogs_Feed_Iframe" src="http://chusete.es/wp-content/uploads/2011/09/Facebook_Dialogs_Feed_Iframe-300x170.png" alt="" width="300" height="170" /></a><strong>Diálogo de amigos</strong></p>
<p>Muestra un diálogo para añadir a un amigo.</p>
<p><a href="http://chusete.es/wp-content/uploads/2011/09/friends-dialog2.png"><img class="aligncenter size-medium wp-image-1105" title="friends-dialog2" src="http://chusete.es/wp-content/uploads/2011/09/friends-dialog2-300x117.png" alt="" width="300" height="117" /></a></p>
<p><strong>Diálogo OAuth</strong></p>
<p>Solicita al usuario unas determinadas autorizaciones, y concede permisos a la aplicación.</p>
<p><a href="http://chusete.es/wp-content/uploads/2011/09/oauth-page.png"><img class="aligncenter size-medium wp-image-1106" title="oauth-page" src="http://chusete.es/wp-content/uploads/2011/09/oauth-page-300x201.png" alt="" width="300" height="201" /></a></p>
<p><strong>Diálogo de Pago</strong></p>
<p>Permite al usuario adquirir nuevos créditos de Facebook.</p>
<p><a href="http://chusete.es/wp-content/uploads/2011/09/2vsp2jb.png"><img class="aligncenter size-medium wp-image-1107" title="2vsp2jb" src="http://chusete.es/wp-content/uploads/2011/09/2vsp2jb-300x171.png" alt="" width="300" height="171" /></a><strong>Diálogo de petición</strong></p>
<p>Diálogo que permite al usuario enviar una petición a uno o más amigos.</p>
<p><a href="http://chusete.es/wp-content/uploads/2011/09/165306_796701067511_703_41122128_101111_n.jpg"><img class="aligncenter size-medium wp-image-1108" title="165306_796701067511_703_41122128_101111_n" src="http://chusete.es/wp-content/uploads/2011/09/165306_796701067511_703_41122128_101111_n-300x277.jpg" alt="" width="300" height="277" /></a></p>
<p><strong>Diálogo de envío</strong></p>
<p>Diálogo para que el usuario envíe un mensaje a algún amigo, a un grupo de amigos, o a una dirección de correo.</p>
<h3><a href="http://chusete.es/wp-content/uploads/2011/09/Facebook_Dialogs_Send.png"><img class="aligncenter size-medium wp-image-1109" title="Facebook_Dialogs_Send" src="http://chusete.es/wp-content/uploads/2011/09/Facebook_Dialogs_Send-300x156.png" alt="" width="300" height="156" /></a>3. <a href="http://developers.facebook.com/docs/authentication/">Autenticación</a> y Permisos</h3>
<p>A menudo necesitaremos que los usuarios nos autoricen a acceder a su información. Por ejemplo, cuando queramos que puedan iniciar sesión en nuestra web utilizando su cuenta de Facebook, o cuando desde nuestra aplicación queramos acceder a determinados campos de su perfil de usuario. Para solicitar esta autorización utilizaremos el Diálogo OAuth.</p>
<p>Cada vez que se utiliza el diálogo OAuth, podremos pasarle información al diálogo acerca de la los permisos de acceso que autorizará el usuario. Te recomiendo que revises la <a href="http://developers.facebook.com/docs/reference/api/permissions/">lista de todos los posibles permisos</a>. Además, ten en cuenta que cuantos más permisos solicites a un usuario, menor será el número de personas que decidan autorizar a tu aplicación.</p>
<p>Existen dos métodos posibles de autenticación: Desde el servidor, o desde el cliente. Pero, para simplificar, podemos decir que son equivalentes el uno al otro.</p>
<h3>4. <a href="http://developers.facebook.com/docs/reference/api">Graph API</a></h3>
<p>El nucleo de Facebook es un grafo social, donde cada persona, foto, evento o página tiene su ID único, y donde existen conexiones entre todos ellos (por ejemplo, amistades, etiquetas en fotos, contenidos compartidos, etc.).</p>
<p>Para acceder a las propiedades de cualquiera de estos objetos accederemos a la URL: <strong>https://graph.facebook.com/ID</strong> cambiando ID por el identificador del objeto que queramos consultar. Como resultado, nos devolverá un objeto JSON.</p>
<p>Por ejemplo, al comienzo de este artículo creamos una aplicación. Puedes coger el App ID de tu aplicación y acceder a su información. Te saldrá algo similar a esto:</p>
<pre name="code" class="javascript">{
   "id": "256797284360192",
   "name": "chusete demo",
   "description": "Aplicaci\u00f3n de pruebas de Chusete",
   "category": "Utilities",
   "subcategory": "News",
   "link": "http://www.facebook.com/apps/application.php?id=256797284360192"
}</pre>
<p>En el caso de los usuarios y de las páginas, cuando tengan un alias, se podrá usar como alternativa al ID.</p>
<p>Por supuesto, todas estas peticiones devuelven por defecto tan solo la información pública de ese objeto/persona. Para acceder a información privada, debemos contar con su autorización. Esta autorización se proporciona mediante el parámetro GET access_token.</p>
<div class="note">
<h3>Graph API Explorer</h3>
<p>Lo mejor para aprender más sobre Graph API es utilizar la herramienta Graph API Explorer, un sencillo explorador para comprobar el resultado de todas las posibles consultas que podemos realizar: <a href="http://developers.facebook.com/tools/explorer">http://developers.facebook.com/tools/explorer</a>. Vamos a ver cómo se usa:</p>
<p>En primer lugar, debemos establecer los permisos que le otorgamos a la herramienta. Para ello pulsamos sobre el botón Get Access Token, donde se desplegarán casillas con todos los posibles permisos (tal como vimos en el apartado anterior, sobre Autenticación). Una vez establecidos, podemos realizar las consulta que queramos desde la columna derecha <em>Conexiones</em>:</p>
<p><a href="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-13-a-las-00.50.30.png"><img class="aligncenter size-full wp-image-1118" title="Captura de pantalla 2011-09-13 a la(s) 00.50.30" src="http://chusete.es/wp-content/uploads/2011/09/Captura-de-pantalla-2011-09-13-a-las-00.50.30.png" alt="" width="245" height="197" /></a></p>
<p>En resumen, en esta utilidad veremos lo siguiente:</p>
<ul>
<li><strong>Access Token</strong> &#8211; Es el parámetro access_token que se proporciona en cada petición al Graph API.</li>
<li><strong>Tipo de petición</strong> &#8211; Es un campo desplegable. Por defecto tendrá el valor GET.</li>
<li><strong>URL de petición</strong> &#8211; Corresponde a la URL sobre la que se realiza la petición.</li>
<li><strong>Resultado</strong> &#8211; Es el bloque gris sobre el que se muestra el resultado JSON.</li>
<li><strong>Conexiones</strong> &#8211; Son enlaces a distintas conexiones sobre el objeto actual.</li>
<li><strong>Fields</strong> &#8211; Campos que muestra el objeto JSON para la petición actual. No tienen por qué mostrarse todos.</li>
</ul>
</div>
<h3>5. <a href="http://developers.facebook.com/docs/opengraph/">Open Graph Protocol</a></h3>
<p><a href="http://chusete.es/wp-content/uploads/2011/09/open_graph_protocol_logo.png"><img class="alignleft size-medium wp-image-1116" title="open_graph_protocol_logo" src="http://chusete.es/wp-content/uploads/2011/09/open_graph_protocol_logo-300x300.png" alt="" width="300" height="300" /></a>Esto no es una tecnología del core de Facebook propiamente dicha, pero sí es algo sobre lo que se apoya. ¿De qué se trata? Voy a explicarlo mediante un ejemplo. Supón que creas una página web de restaurantes, donde cada uno tiene su propia URL. Un día un usuario comparte esta URL en Facebook. ¿Qué ocurrirá? Que Facebook elegirá la información y las imágenes que él considere relevante. Pero, ¿y si quisiéramos nosotros decirle a Facebook (y otras redes sociales) la información que debe mostrar? Para dar respuesta a eso surge el protocolo Open Graph.</p>
<p>En otras palabras: Hace que nuestras páginas web se conviertan en objetos &#8220;del mundo real&#8221; con el que pueden interactuar las redes sociales. Películas, restaurantes, celebridades, etc.</p>
<p>En el caso concreto de Facebook, además, cuando un usuario haga clic en el plugin del botón &#8220;Me gusta&#8221; de una de tus páginas, será equivalente a que hiciera clic en &#8220;Me gusta&#8221; de alguna de las Facebook Pages, por lo que podrás enviarle actualizaciones a su Feed. Mola, ¿no?</p>
<p>Su funcionamiento no podría ser más sencillo. Open Graph Protocol está basado en <a href="http://es.wikipedia.org/wiki/RDFa">RDFa</a>, por lo que mediante etiquetas meta puedes añadir semántica a tus páginas. Además, para una correcta integración con Facebook, debes añadir el plugin del botón &#8220;Me gusta&#8221;.</p>
<p>Para más información, revisa la página oficial de Open Graph Protocol: <a href="http://ogp.me/">http://ogp.me/</a></p>
<h3>6. Otras tecnologías</h3>
<p>Además de todas las tecnologías que hemos visto, existen otras de tipo <em>avanzado</em> que, por lo general, no será necesario usarlas. En concreto estaríamos hablando de:</p>
<ul>
<li><strong><a href="http://developers.facebook.com/docs/reference/fql">FQL</a></strong>. Facebook Query Language, o Lenguaje de consultas de Facebook. Similar a SQL, sirve para consultar los datos que ofrece Graph API.</li>
<li><strong><a href="http://developers.facebook.com/docs/internationalization">API de internacionalización</a></strong>. Mediante esta API puedes aprovechar la infraestructura de internacionalización de Facebook para tu aplicación.</li>
<li><strong><a href="http://developers.facebook.com/docs/creditsapi">API de créditos</a></strong>. Para que los usuarios puedan realizar pagos de créditos de Facebook para utilizar en tu aplicación.</li>
<li><strong><a href="http://developers.facebook.com/docs/reference/ads-api">API de publicidad</a></strong>. Permite crear y gestionar mediante código tus campañas publicitarias.</li>
<li><strong><a href="http://developers.facebook.com/docs/chat">API de Chat</a></strong>. Para aquellos desarrolladores que quieran integrar el chat de Facebook en sus aplicaciones, mediante el protocolo estándar <a href="http://es.wikipedia.org/wiki/Extensible_Messaging_and_Presence_Protocol">Jabber/XMPP</a>.</li>
</ul>
<p><strong>APIs obsoletas</strong>. Además, existen determinadas APIs que han quedado obsoletas y a las que pronto Facebook dejará de dar soporte, como la API REST, el lenguaje de marcado FBML, o la API JavaScript.</p>
<h2>SDKs</h2>
<p>Por último, vamos a repasar los distintos kits de desarrollo que nos regala Facebook. Cabe destacar que no es imprescindible utilizarlos, ya que podremos realizar la autenticación, invocación de diálogos, o las llamadas a la API a mano. Pero, como podrás imaginar, resulta mucho más sencillo utilizar una herramienta ya probada que lo haga por nosotros.</p>
<p>Existen cuatro SDKs:</p>
<ol>
<li><a href="http://developers.facebook.com/docs/reference/javascript/">JavaScript SDK</a>.</li>
<li><a href="http://github.com/facebook/php-sdk/">PHP SDK</a>.</li>
<li><a href="http://developers.facebook.com/docs/reference/ios">iOS SDK (iPhone &amp; iPad)</a>.</li>
<li><a href="http://developers.facebook.com/docs/reference/android">Android SDK</a>.</li>
</ol>
<p>Aquí vamos a hablar de los dos primeros.</p>
<h3>1. JavaScript SDK</h3>
<p>Permite realizar llamadas a la Graph API, crear diálogos, renderizar los Social Plugins, además de otras muchas cosas. Para usar el SDK, debemos  intrducir el siguiente código a nuestra aplicación:</p>
<pre name="code" class="javascript">&lt;div id="fb-root"&gt;&lt;/div&gt;
&lt;script src="http://connect.facebook.net/en_US/all.js"&gt;&lt;/script&gt;
&lt;script&gt;
  FB.init({
    appId  : 'ID DE TU APP',
    status : true, // comprobar estado de login
    cookie : true, // habilitar cookies para permitir al servidor acceder a la sesión
    xfbml  : true, // ejecutar código XFBML
    channelURL : 'http://WWW.MIDOMINIO.COM/channel.html', // fichero channel.html
    oauth  : true // habilita OAuth 2.0
  });
&lt;/script&gt;</pre>
<p>Y en el fichero channel.html añades el siguiente contenido:</p>
<pre name="code" class="javascript">&lt;script src="http://connect.facebook.net/en_US/all.js"&gt;&lt;/script&gt;</pre>
<p>Y ya lo tienes. Tu página está preparada para ejecutar código del SDK JavaScript de Facebook.</p>
<div class="note">
<h3>JavaScript Test Console</h3>
<p>Del mismo modo que teníamos una herramienta para poder probar la Graph API, también tenemos una <a href="http://developers.facebook.com/tools/console/">consola de desarrollo para el SDK de JavaSript</a>. Para ello, accedemos a <a href="http://developers.facebook.com/tools/console/">http://developers.facebook.com/tools/console/</a> pulsamos sobre Login para concederle permisos a la aplicación de la consola de desarrollo, introducimos el código JavaScript que queremos probar, y pulsamos sobre &#8220;Run Code&#8221;.</p>
<p>Para hacer las cosas más fáciles, podemos pulsar sobre el botón &#8220;Examples&#8221; al pie del textarea, y seleccionamos el ejemplo que deseamos probar.</p>
</div>
<h3>2. PHP SDK</h3>
<p>El SDK oficial para PHP de Facebook es un proyecto open source que se encuentra alojado en GitHub:  <a href="https://github.com/facebook/php-sdk/">https://github.com/facebook/php-sdk/</a>.</p>
<p>Si bien existe un <a href="https://github.com/facebook/php-sdk/blob/master/examples/example.php">ejemplo básico</a>, pero completo, sobre su uso, vamos a resumir aquí las principales operaciones:</p>
<p>Código de inicialización:</p>
<pre name="code" class="php">require 'php-sdk/src/facebook.php';

$facebook = new Facebook(array(
  'appId'  =&gt; 'TU_APP_ID',
  'secret' =&gt; 'TU_APP_SECRET',
));

// Obtener ID de usuario
$user = $facebook-&gt;getUser();</pre>
<p>Llamada a la API (Graph API):</p>
<pre name="code" class="php">if ($user) {
  try {
    // Procedemos sabiendo que tenemos un usuario que ha iniciado sesión y concedido permisos.
    $user_profile = $facebook-&gt;api('/me');
  } catch (FacebookApiException $e) {
    error_log($e);
    $user = null;
  }
}</pre>
<p>Obtener URLs de inicio de sesión y de salida:</p>
<pre name="code" class="php">if ($user) {
  $logoutUrl = $facebook-&gt;getLogoutUrl();
} else {
  $loginUrl = $facebook-&gt;getLoginUrl();
}</pre>
<h2>Resumen</h2>
<p>Este ha sido un post bastante extenso, al que le seguirán otros con distintos casos de uso. Por lo pronto, hemos visto que es posible implementar distintos tipos de aplicaciones para Facebook: para el móvil, para una página web, y empotradas en Facebook. Hemos revisado paso a paso el proceso de alta de una nueva aplicación, donde establecemos los parámetros básicos, el nombre, logo, descripción, etc. También hemos revisado todas las tecnologías que nos ofrece Facebook para desarrollar aplicaciones en su ecosistema: Social Plugins, Diálogos, Autenticación y permisos, Graph API y Open Graph. Por último, hemos repasado las distintas bibliotecas que nos da Facebook para facilitar el desarrollo de aplicaciones en JavaScript, PHP, iOS y Android, centrándonos en las dos primeras.</p>
<p>Ahora que conocemos bien todo marco de trabajo sobre el que se apoyan las aplicaciones en Facebook, estamos listos para comenzar. En el siguiente post realizaremos una pequeña aplicación que sirva como demo de todos estos conceptos.
<div class="tweetmeme_button" style="float: left; margin-right: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fchusete.es%2F2011%2F09%2F13%2Fintroduccion-a-la-programacion-en-facebook%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fchusete.es%2F2011%2F09%2F13%2Fintroduccion-a-la-programacion-en-facebook%2F&amp;source=chuso&amp;style=normal&amp;service=bit.ly&amp;service_api=R_86054639b9f90148987197dfdc061697&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
]]></content:encoded>
			<wfw:commentRss>http://chusete.es/2011/09/13/introduccion-a-la-programacion-en-facebook/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>¿Por qué dicen que #democraciarealya es una iniciativa del PSOE?</title>
		<link>http://chusete.es/2011/05/19/%c2%bfpor-que-dicen-que-democraciarealya-es-una-iniciativa-del-psoe/</link>
		<comments>http://chusete.es/2011/05/19/%c2%bfpor-que-dicen-que-democraciarealya-es-una-iniciativa-del-psoe/#comments</comments>
		<pubDate>Wed, 18 May 2011 22:06:08 +0000</pubDate>
		<dc:creator>chusete</dc:creator>
				<category><![CDATA[comunicados]]></category>
		<category><![CDATA[democraciarealya]]></category>
		<category><![CDATA[nolesvotes]]></category>

		<guid isPermaLink="false">http://chusete.es/?p=1069</guid>
		<description><![CDATA[Aviso &#8211; Lee esto antes Tras escribir este artículo he visto que el encargado del dominio democreaciarealya.es ya había escrito un post en Barrapunto desmintiendo lo que dicen sobre él: http://barrapunto.com/~manje/bitacora Esta noche estamos viendo en varios medios de comunicación, afines a la derecha, decir que tanto la iniciativa #democraciarealya como #acampadasol fueron gestadas por [...]]]></description>
			<content:encoded><![CDATA[<div class="note">
<h3>Aviso &#8211; Lee esto antes</h3>
<p>Tras escribir este artículo he visto que el encargado del dominio democreaciarealya.es ya había escrito un post en Barrapunto desmintiendo lo que dicen sobre él:<br />
<a href="http://barrapunto.com/~manje/bitacora">http://barrapunto.com/~manje/bitacora</a></p>
</div>
<p>Esta noche estamos viendo en varios medios de comunicación, afines a la derecha, decir que tanto la iniciativa <a href="https://twitter.com/#!/search/%23democraciarealya">#democraciarealya</a> como <a href="https://twitter.com/#!/search/%23acampadasol">#acampadasol</a> fueron gestadas por el PSOE. ¿Por qué lo dicen? ¿Cómo pueden pensar algo así cuando no hace más que gritarse &#8220;no LES votes&#8221;?</p>
<p>Dicen &#8220;<em>El titular del dominio democraciarealya es el dirigente de una escisión de Izquierda Unida, que ahora forma parte de la web redsocialista, por tanto las acampadas de Sol son iniciativa del PSOE y se están gestando desde el 1 de marzo de este año, no se trata de algo espontáneo</em>&#8220;. Veamos en qué se basa su sesudo estudio <img src='http://chusete.es/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Gracias a los <a title="puedes consultarlo aquí" href="https://www.nic.es/index.action">datos whois</a> del dominio democraciarealya.es, han averiguado el nombre del contacto administrativo y técnico; se trata de Manuel J R E. <strong>Primer fallo</strong>: Manuel J. es el contacto administrativo y técnico, no el titular. Éste es el Colectivo de Educador@s en Barrio Arrabal. Pero ok, asumamos que Manuel J. es el titular.</p>
<p>Si buscamos su nombre en Google, en el cuarto resultado vemos lo siguiente:</p>
<p><a href="http://chusete.es/wp-content/uploads/2011/05/Captura-de-pantalla-2011-05-18-a-las-23.36.411.png"><img class="size-full wp-image-1079 alignnone aligncenter" title="Captura de pantalla 2011-05-18 a las 23.36.41" src="http://chusete.es/wp-content/uploads/2011/05/Captura-de-pantalla-2011-05-18-a-las-23.36.411.png" alt="" width="529" height="81" /></a></p>
<p>¿Qué es una Red de blogs? Se trata de una página que muestra automáticamente todos los artículos de aquellos blogs que estén vinculados a esta red. En concreto este artículo proviene de <a href="http://opiniones.wordpress.com/2010/07/21/www-noticiasdejerez-net-el-meneame-jerezano/">este otro blog</a>, y habla de que Manuel J. R. E. ha realizado una página web para compartir noticias de Jerez.</p>
<p><strong>Segundo fallo</strong>: que su nombre aparezca en esa red de blogs, no lo vincula con el PSOE. Es como decir que José María Aznar es socialista, porque su nombre <a href="http://redblogsocialistas.org/?s=jos%C3%A9+mar%C3%ADa+aznar">también aparece en la web redblogsocialistas.org</a>. Como en &#8220;Red de Blogs Socialistas&#8221; ha salido publicada una noticia que habla de la nueva página web que ha creado Manuel J. R. E. (persona de contacto administrativo y técnico de democraciarealya.es), entonces concluyen que Manuel es socialista.</p>
<p>Luego llama la atención la precisión con la fecha en que &#8220;el PSOE inició todo esto&#8221;: el 1 de marzo. ¿Por qué el 1 y no el 26 de febrero? Simple y llanamente se limitan a decir la fecha de alta del dominio democraciarealya.es <img src='http://chusete.es/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Esto es de una candidez mental tal que uno no puede evitar sonreir.</p>
<p>Por último, tratan de deslegitimar las declaraciones de los acampados en que dicen que esto es un movimiento espontáneo. ¿No se han enterado de que una cosa es la manifestación ORGANIZADA del 15M, y otra la acampada espontánea que surgió minutos después por parte de unas 50 personas de las que acudieron? Por tanto <strong>tercer fallo</strong>: Confundir el movimiento #democraciarealya con @acampadasol. No hay más que leer la propia <a href="http://democraciarealya.es/">web de democraciarealya</a>:</p>
<blockquote><p>Democracia real YA <strong>apoya las acampadas espontáneas</strong> convocadas para esta misma semana. Convocatorias también desprovistas de símbolos políticos o sindicales y promovidas por asistentes a las manifestaciones del domingo, pero<strong> no convocadas directamente por Democracia real YA ni por los organizadores de las manifestaciones del 15 de mayo</strong>.</p></blockquote>
<p>Así es. En esto se basan los sesudos informes que presentan los medios de desinformación que manipulan a la ciudadanía. Lo peor de todo, nuestras personas más mayores los creen.</p>
<p>Copiad y pegad este artículo donde queráis. Que no deslegitimen este movimiento de todos nosotros.</p>
<p><strong>Edit</strong>: Efectivamente, el titular del dominio (colabore o no con #democraciarealya), formó parte de las listas de <a href="http://es.wikipedia.org/wiki/Izquierda_Andaluza">Izquierda Andaluza</a>. De modo que es evidente que no tuvo vinculación alguna con el PSOE.
<div class="tweetmeme_button" style="float: left; margin-right: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fchusete.es%2F2011%2F05%2F19%2F%25c2%25bfpor-que-dicen-que-democraciarealya-es-una-iniciativa-del-psoe%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fchusete.es%2F2011%2F05%2F19%2F%25c2%25bfpor-que-dicen-que-democraciarealya-es-una-iniciativa-del-psoe%2F&amp;source=chuso&amp;style=normal&amp;service=bit.ly&amp;service_api=R_86054639b9f90148987197dfdc061697&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
]]></content:encoded>
			<wfw:commentRss>http://chusete.es/2011/05/19/%c2%bfpor-que-dicen-que-democraciarealya-es-una-iniciativa-del-psoe/feed/</wfw:commentRss>
		<slash:comments>48</slash:comments>
		</item>
	</channel>
</rss>

