<?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>Emilio Cobos</title>
	<atom:link href="https://emiliocobos.net/feed/" rel="self" type="application/rss+xml" />
	<link>https://emiliocobos.net</link>
	<description>Diseño y desarrollo web, Wordpress y Blogger</description>
	<lastBuildDate>Wed, 12 Nov 2014 22:55:47 +0000</lastBuildDate>
	<language>es</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.1.3</generator>
	<item>
		<title>Pasar de blogger a wp, mejor que nunca!</title>
		<link>https://emiliocobos.net/blogger-a-wordpress-mejor/</link>
					<comments>https://emiliocobos.net/blogger-a-wordpress-mejor/#comments</comments>
		
		<dc:creator><![CDATA[Emilio Cobos Álvarez]]></dc:creator>
		<pubDate>Wed, 12 Nov 2014 22:55:47 +0000</pubDate>
				<category><![CDATA[Blogger]]></category>
		<category><![CDATA[WordPress]]></category>
		<guid isPermaLink="false">http://emiliocobos.net/?p=821</guid>

					<description><![CDATA[<p>Hace mucho publiqué un pequeño script para migrar de blogger a wp. Lo he reescrito, para que sea mucho más intuitivo, mucho más óptimo en cuanto al uso de la&#8230; <a class="jump-link" href="https://emiliocobos.net/blogger-a-wordpress-mejor/">Leer más <span class="meta-nav">&#187;</span></a></p>
<p>The post <a href="https://emiliocobos.net/blogger-a-wordpress-mejor/">Pasar de blogger a wp, mejor que nunca!</a> first appeared on <a href="https://emiliocobos.net">Emilio Cobos</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>Hace mucho publiqué un pequeño script para <a href="http://emiliocobos.net/migrar-de-blogger-a-wordpress-la-guia-definitiva/" title="Migrar de blogger a WordPress: La guía definitiva">migrar de blogger a wp</a>.</p>

<p>Lo he reescrito, para que sea mucho más intuitivo, mucho más óptimo en cuanto al uso de la memoria, y en cuanto a la detección de errores.</p>

<p>El tutorial antiguo sigue siendo válido, lo único que ahora deberíais usar <a href="https://github.com/ecoal95/blogger-to-wordpress/archive/master.zip">estos archivos</a>, y no tenéis que subir el xml a vuestro servidor, sino indicarlo cuando abráis la página de migración.</p>

<a href="http://emiliocobos.net/wp-content/uploads/2014/11/Captura-de-pantalla-de-2014-11-12-235242.png"><img decoding="async" loading="lazy" src="http://emiliocobos.net/wp-content/uploads/2014/11/Captura-de-pantalla-de-2014-11-12-235242.png" alt="Blogger a wordpress v2" width="1366" height="768" class="alignnone size-full wp-image-823" srcset="https://emiliocobos.net/wp-content/uploads/2014/11/Captura-de-pantalla-de-2014-11-12-235242.png 1366w, https://emiliocobos.net/wp-content/uploads/2014/11/Captura-de-pantalla-de-2014-11-12-235242-300x168.png 300w, https://emiliocobos.net/wp-content/uploads/2014/11/Captura-de-pantalla-de-2014-11-12-235242-1024x575.png 1024w" sizes="(max-width: 1366px) 100vw, 1366px" /></a>

<p>Ah, <strong>importante!</strong> Un navegador actualizado ;)</p>

<p>Este post es corto, he usado muchas cosas chulas para hacerlo, pero no me da tiempo a explicarlas todas una a una. Entraré con más detalle más adelante.</p>

<p>Si tenéis alguna duda, por favor, dejarla en los comentarios, que no muerdo :P</p><p>The post <a href="https://emiliocobos.net/blogger-a-wordpress-mejor/">Pasar de blogger a wp, mejor que nunca!</a> first appeared on <a href="https://emiliocobos.net">Emilio Cobos</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://emiliocobos.net/blogger-a-wordpress-mejor/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>Sigo vivo!</title>
		<link>https://emiliocobos.net/sigo-vivo/</link>
					<comments>https://emiliocobos.net/sigo-vivo/#comments</comments>
		
		<dc:creator><![CDATA[Emilio Cobos Álvarez]]></dc:creator>
		<pubDate>Thu, 16 Oct 2014 23:42:09 +0000</pubDate>
				<category><![CDATA[Sin categoría]]></category>
		<guid isPermaLink="false">http://emiliocobos.net/?p=814</guid>

					<description><![CDATA[<p>Sí, aunque parezca que no, sigo vivo :P Llevaba muchísimo sin pasarme por aquí la verdad. Vamos a ver qué tal se nos da esto&#8230; Razones de mi ausencia He&#8230; <a class="jump-link" href="https://emiliocobos.net/sigo-vivo/">Leer más <span class="meta-nav">&#187;</span></a></p>
<p>The post <a href="https://emiliocobos.net/sigo-vivo/">Sigo vivo!</a> first appeared on <a href="https://emiliocobos.net">Emilio Cobos</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>Sí, aunque parezca que no, sigo vivo :P</p>

<p>Llevaba muchísimo sin pasarme por aquí la verdad. Vamos a ver qué tal se nos da esto&#8230;</p>

<h3>Razones de mi ausencia</h3>

<p>He estado ausente de esta web por bastantes razones, algunas familiares, algo de pereza, pero&#8230; También ha habido algo de <strong>trabajo</strong> de por medio!</p>

<p>He estado trabajando en mi ciudad con una empresa de desarrollo web <a target="_blank" href="http://innovega.net">Innovega</a> (no, no hay tiempo para rediseñar la web, están hasta arriba de trabajo <i class="icon guino">;)</i>, pero para que os hagáis una idea están detrás de proyectos como <a target="_blank" href="http://groopify.me">Groopify</a>), programando en <strong>Ruby on Rails</strong>!</p>

<p>Lo cierto es que para desarrollar rápido una aplicación compleja es otro mundo: Probad ruby y no volveréis a querer usar PHP en vuestra vida, ni con framework ni sin él <i class="icon guino">;)</i>.</p>

<p>También he tocado algo de <strong>angular.js</strong>, y he mejorado mi capacidad de organización (poco, todo sea dicho&#8230;), además de haber hecho mis pinitos con <strong>Django</strong>, que es bastante similar a Rails, aunque prefiero el último.</p>

<p>Luego está la <strong>facultad</strong>, donde programamos en <strong>C</strong> y&#8230; lo creáis o no me gusta!</p>

<p>Y&#8230; Eso ha sido todo lo que he estado haciendo este tiempo! Podéis ver las ultimas cosillas de código libre que he ido publicando en <a href="https://github.com/ecoal95">GitHub</a>:</p>

<ul>
<li><strong><a href="https://github.com/ecoal95/clib">Clib</a></strong>: Una biblioteca de funciones en C, porque no me gusta programar las cosas cinco veces&#8230;</li>
<li><strong><a href="https://github.com/ecoal95/editable-input">Editable input</a></strong>: Un pequeño javascript que programé para actualizar un par de campos al doble click en rails&#8230;</li>
<li>Tristemente, pero no he publicado nada más de código abierto en bastante tiempo&#8230; Y tengo ganas!</li>
</ul>

<h3>Cosas que hacer</h3>

<p>Por ahora me toca hacer un porrón de cosas:</p>

<ul>
<li><strong>Contestar comentarios</strong>: Hay como millones!</li>
<li><strong>Dar soporte a <a href="http://emiliocobos.net/ec-stars-rating-wordpress-plugin/">EC-stars-rating</a></strong></li>
<li><strong>Actualizar</strong> algún artículo antiguo que sigue recibiendo visitas (<a href="http://emiliocobos.net/modalbox-una-ventana-modal-propia/">modalBox</a> y sobre todo <a href="http://emiliocobos.net/migrar-de-blogger-a-wordpress-la-guia-definitiva/">Migrar de blogger a WP</a>)</li>
<li><strong>Rediseñar esto</strong> (a ver qué sale).</li>
<li><strong>Programar</strong> mucho</li>
<li><strong>Escribir aquí</strong></li>
</ul>

<h3>Y ahí es donde entráis vosotros&#8230;</h3>

<p>La verdad es que <strong>no sé de qué leches escribir</strong> porque tengo muchísimo de lo que escribir: que si CSS, Javascript, Ruby on Rails, Django (podríamos animarnos a hacer un mini proyecto), C, PHP,  programación en general&#8230;</p>

<p>Así que he dicho&#8230; Pues si no me decido, <strong>a gusto del consumidor</strong>. Y he plantado una encuesta en la sidebar&#8230;</p>

<p>Sois libres de votar, o incluso mejor <strong>proponer en los comentarios</strong> <i class="icon guino">;)</i>.</p>

<p><strong>PD:</strong> Si me decís qué preferís, si artículos más técnicos o más para principiantes, me hacéis un favor también :P.</p><p>The post <a href="https://emiliocobos.net/sigo-vivo/">Sigo vivo!</a> first appeared on <a href="https://emiliocobos.net">Emilio Cobos</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://emiliocobos.net/sigo-vivo/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>Router en PHP: Urls dinámicas sin saber .htaccess!</title>
		<link>https://emiliocobos.net/router-en-php/</link>
					<comments>https://emiliocobos.net/router-en-php/#comments</comments>
		
		<dc:creator><![CDATA[Emilio Cobos Álvarez]]></dc:creator>
		<pubDate>Wed, 22 Jan 2014 13:48:40 +0000</pubDate>
				<category><![CDATA[PHP]]></category>
		<guid isPermaLink="false">http://emiliocobos.net/?p=787</guid>

					<description><![CDATA[<p>Una de las partes más importantes de una web, sobre todo de cara al SEO, son las url utilizadas. A nadie le gusta que en su blog las urls aparezcan&#8230; <a class="jump-link" href="https://emiliocobos.net/router-en-php/">Leer más <span class="meta-nav">&#187;</span></a></p>
<p>The post <a href="https://emiliocobos.net/router-en-php/">Router en PHP: Urls dinámicas sin saber .htaccess!</a> first appeared on <a href="https://emiliocobos.net">Emilio Cobos</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>Una de las partes más importantes de una web, sobre todo de cara al SEO, son las url utilizadas. A nadie le gusta que en su blog las urls aparezcan con feos parámetros obligatorios en la query, como wordpress por defecto:</p>

<pre><code>http://emiliocobos.net/?p=787</code></pre>

<p>Hoy os presento <strong>un par de clases en php que os facilitarán la tarea de crear webs con <em>urls bonitas</em></strong>:</p>

<p style='text-align: center;'><a href="http://emiliocobos.net/demos/php-router/" target="_blank" title="Link a la demo" class="boton">Demo</a> <a download href="https://github.com/ecoal95/php-router/archive/master.zip" target="_blank" title="Link de descarga" class="boton">Descarga</a> <a href="https://github.com/ecoal95/php-router" target="_blank" title="Ver en Github" class="boton">Ver en GitHub</a></p>


<p>Para lograr urls bonitas hay dos alternativas:</p>

<h2>1- .htaccess</h2>
<p>Usar <code>mod_rewrite</code> es a priori la más «simple» de conseguir urls bonitas, ya que viene integrada en nuestro servidor, pero tiene muchos inconvenientes:</p>
<ul>
	<li><strong>Es poco mantenible:</strong> El día que quieras cambiar la estructura de una url (pasar un nombre de usuario en vez de una id) tendrás que cambiar tanto tu código PHP como tu <code>.htaccess</code></li>
	<li><strong>Al final trabajas con la query string</strong>: Puede haber conflictos entre parámetros pasados por el usuario y los tuyos, o que cualquier otro parámetro sea ignorado. Supongamos que <code>/user/1</code> redirige mediante apache a <code>/user.php?uid=1</code>. Si quisieras usar un parámetro get para otra cosa, seguramente no funcione ir a <code>/user/4?edit</code>, sino que habrá que crear otra regla específica.</li>
</ul>

<h2>2- Redirigir todas las solicitudes a <code>index.php</code> y desde ahí leer</h2>
<p>Ésta es la opción más sana (sobre todo porque <strong>mantienes toda tu lógica en el mismo sitio</strong>), se consigue con un <code>.htaccess</code> tal que así:</p>
<pre data-language="htaccess" data-nohighlight><code>&lt;IfModule mod_rewrite.c&gt;
	RewriteEngine on

	RewriteCond %{REQUEST_FILENAME} !-f
	RewriteCond %{REQUEST_FILENAME} !-d

	RewriteRule ^(.*)$ index.php/$1 [L]
&lt;/IfModule&gt;</code></pre>

<p>Se pueden leer las urls a mano (mediante <code>$_SERVER['REQUEST_URI']</code>), pero yo he hecho un par de clases para facilitar la tarea, permitiéndote usar expresiones regulares, y dejándote elegir métodos específicos (<code>GET</code>, <code>POST</code>&#8230;).</p>

<h3>Un ejemplo sencillo:</h3>
<p>Nuestro index.php con nuestra nueva configuración para hacer el rewrite anterior quedaría así:</p>
<pre><code>&lt;?php
include 'src/Router/Route.php';
include 'src/Router/Router.php';

// Si está en el directorio raíz dejar así, si no especificar como primer parámetro <code>'/la-subcarpeta'</code>
$router = new Router\Router();

$router->add('/', function() {
    // Mostrar el home
});

$router->add('/user/([0-9]+)', function($user_id) {
    // Ya tenemos la id del usuario en la variable $user_id, sin tener que acceder a $_GET ni nada por el estilo
    // En este caso habría que comprobar si el usuario existe, y si no mandar un 404
});

$router->add('/*.', function() {
    // 404
});
?>
</code></pre>

<h3>Más ejemplos:</h3>
<p>Podéis ver más ejemplos en github, donde se encuentra el código, o la demo en vivo:</p>

<ul>
	<li><a href="/demos/php-router/hola-mundo">Ejemplo de url estática</a> (Hola, mundo).</li>
	<li><a href="/demos/php-router/hola-Juan">Ejemplo de url dinámica</a> (cambia «Juan» en la url por una serie de palabras separadas por guiones).</li>
	<li><a href="/demos/php-router/hola/Pepe%20Perez">Ejemplo de url dinámica con subdirectorios</a> (cambia «Pepe Perez»)</li>
</ul>

<h2>Demo y descarga</h2>

<p style='text-align: center;'><a href="http://emiliocobos.net/demos/php-router/" target="_blank" title="Link a la demo" class="boton">Demo</a> <a download href="https://github.com/ecoal95/php-router/archive/master.zip" target="_blank" title="Link de descarga" class="boton">Descarga</a> <a href="https://github.com/ecoal95/php-router" target="_blank" title="Ver en Github" class="boton">Ver en GitHub</a></p><p>The post <a href="https://emiliocobos.net/router-en-php/">Router en PHP: Urls dinámicas sin saber .htaccess!</a> first appeared on <a href="https://emiliocobos.net">Emilio Cobos</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://emiliocobos.net/router-en-php/feed/</wfw:commentRss>
			<slash:comments>31</slash:comments>
		
		
			</item>
		<item>
		<title>Sorteo de 3 plantillas premium para WordPress via TemplateMonster [CERRADO]</title>
		<link>https://emiliocobos.net/gana-3-plantillas-para-wordpress/</link>
					<comments>https://emiliocobos.net/gana-3-plantillas-para-wordpress/#comments</comments>
		
		<dc:creator><![CDATA[Emilio Cobos Álvarez]]></dc:creator>
		<pubDate>Mon, 23 Dec 2013 06:50:30 +0000</pubDate>
				<category><![CDATA[WordPress]]></category>
		<guid isPermaLink="false">http://emiliocobos.net/?p=775</guid>

					<description><![CDATA[<p>El otro día contactó TemplateMonster para ofrecerme realizar un sorteo de sus plantillas en esta web. Como os podéis imaginar por el título de la entrada, acepté ;) Las bases&#8230; <a class="jump-link" href="https://emiliocobos.net/gana-3-plantillas-para-wordpress/">Leer más <span class="meta-nav">&#187;</span></a></p>
<p>The post <a href="https://emiliocobos.net/gana-3-plantillas-para-wordpress/">Sorteo de 3 plantillas premium para WordPress via TemplateMonster [CERRADO]</a> first appeared on <a href="https://emiliocobos.net">Emilio Cobos</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>El otro día contactó <a href="http://templatemonster.com/es" target="_blank">TemplateMonster</a> para ofrecerme realizar un sorteo de sus plantillas en esta web. Como os podéis imaginar por el título de la entrada, acepté <i class="icon guino">;)</i></p>

<p>Las bases son las siguientes:</p>
<ul>
	<li>Se regalarán <strong>tres plantillas para WordPress</strong>, una para cada uno de los tres ganadores del sorteo.</li>
	<li>Para <strong>participar</strong>, sólo es necesario especificar <strong>en un comentario</strong> usando tu nombre real, <strong>el número de la plantilla</strong> que te gustaría conseguir (puedes verlas <a href="http://www.templatemonster.com/es/temas-wordpress-tipo/" target="_blank">aquí</a>, cada una tiene un número distinto), y la <strong>razón por la que te gustaría conseguirla</strong>.</li>
	<li>Sólo es válido un comentario por persona (supongo que eso ya lo imaginabas <i class="icon guino">;)</i>).</li>
	<li>El sorteo comienza en el momento que la entrada esté publicada (así que si lees esto ya puedes participar) y acaba el <strong>lunes 30 de diciembre a las 12:00</strong>. Cualquier comentario a partir de esa fecha ya no será válido. Los números serán escogidos aleatoriamente usando <a href="http://random.org">random.org</a>. Yo seré el encargado y subiré a esta entrada la captura.</li>
	<li>Tras haber elegido a los ganadores me pondré en contacto con ellos y se les entregará el premio.</li>
</ul>
<p>Cualquier duda, o lo que sea, ya sabéis, no muerdo.</p>

<h2>Actualización: Ganadores</h2>
<p>Estoy esperando a que me conteste TemplateMonster sobre la forma de distribuir las plantillas, pero aquí están las capturas que acreditan a los ganadores:</p>

<a href="http://emiliocobos.net/wp-content/uploads/2013/12/random-input.png"><img decoding="async" loading="lazy" width="1440" height="900" src="http://emiliocobos.net/wp-content/uploads/2013/12/random-input.png" alt="random-input"  class="alignnone size-full wp-image-781" srcset="https://emiliocobos.net/wp-content/uploads/2013/12/random-input.png 1440w, https://emiliocobos.net/wp-content/uploads/2013/12/random-input-300x187.png 300w, https://emiliocobos.net/wp-content/uploads/2013/12/random-input-1024x640.png 1024w" sizes="(max-width: 1440px) 100vw, 1440px" /></a>

<a href="http://emiliocobos.net/wp-content/uploads/2013/12/random-out.png"><img decoding="async" loading="lazy" width="1440" height="900" src="http://emiliocobos.net/wp-content/uploads/2013/12/random-out.png" alt="random-out" class="alignnone size-full wp-image-782" srcset="https://emiliocobos.net/wp-content/uploads/2013/12/random-out.png 1440w, https://emiliocobos.net/wp-content/uploads/2013/12/random-out-300x187.png 300w, https://emiliocobos.net/wp-content/uploads/2013/12/random-out-1024x640.png 1024w" sizes="(max-width: 1440px) 100vw, 1440px" /></a><p>The post <a href="https://emiliocobos.net/gana-3-plantillas-para-wordpress/">Sorteo de 3 plantillas premium para WordPress via TemplateMonster [CERRADO]</a> first appeared on <a href="https://emiliocobos.net">Emilio Cobos</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://emiliocobos.net/gana-3-plantillas-para-wordpress/feed/</wfw:commentRss>
			<slash:comments>10</slash:comments>
		
		
			</item>
		<item>
		<title>Conceptos básicos de programación independientes del lenguaje</title>
		<link>https://emiliocobos.net/conceptos-basicos-de-programacion/</link>
					<comments>https://emiliocobos.net/conceptos-basicos-de-programacion/#comments</comments>
		
		<dc:creator><![CDATA[Emilio Cobos Álvarez]]></dc:creator>
		<pubDate>Wed, 18 Dec 2013 23:57:20 +0000</pubDate>
				<category><![CDATA[Programación general]]></category>
		<guid isPermaLink="false">http://emiliocobos.net/?p=768</guid>

					<description><![CDATA[<p>Bueno, mucho tiempo llevaba sin escribir aquí, y no por falta de ganas, precisamente. Lo normal es que hable de desarrollo web, que es lo que más me gusta, pero&#8230; <a class="jump-link" href="https://emiliocobos.net/conceptos-basicos-de-programacion/">Leer más <span class="meta-nav">&#187;</span></a></p>
<p>The post <a href="https://emiliocobos.net/conceptos-basicos-de-programacion/">Conceptos básicos de programación independientes del lenguaje</a> first appeared on <a href="https://emiliocobos.net">Emilio Cobos</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>Bueno, mucho tiempo llevaba sin escribir aquí, y no por falta de ganas, precisamente.</p>

<p>Lo normal es que hable de desarrollo web, que es lo que más me gusta, pero en la universidad estamos con C a saco, y si de algo me doy cuenta, es que hay cosas que independientemente del lenguaje, son universales. Hago este post como recopilación personal de los aspectos que más importancia tienen en mi opinión como programador.</p>

<p>Como siempre, estoy abierto a la discusión, rectificación o adición de cosas <i class="icon guino"></i></p>

<h2>Organización</h2>
<p><strong>Un código bien organizado es más fácil de leer, usar y mantener.</strong></p>
<p>Una de las cosas que me ha enseñado haber «empezado a programar de cero» (en clase no me dejaban usar ni una mísera función, por el hecho de que no lo habíamos dado), es de la importancia que tiene organizar tu código.</p>
<p>Tener organizado el código significa:</p>
<h3>Que no se repita</h3>
<p>Esto a los guiris les encanta llamarlo <strong>DRY (Don&#8217;t Repeat Yourself)</strong>. Para hacer el código más mantenible lo ideal es que cada instrucción sólo se repita una vez, y así sólo habrá que cambiarla una vez, entenderla una vez&#8230; y sobre todo, programarla una vez.</p>
<p>Si te encuentras con esto:</p>
<pre data-language="c"><code>int main(void) {
	// Lo ideal sería que la array en este caso fuera dinámica, pero es un ejemplo...
	int v[12];
	size_t length;
	printf("Introduce cuántos números vas a meter (máximo 12):");
	do {
		scanf("%u", &length);
		if ( length > 12 ) {
			printf("Dimensión nó válida, ha de ser menor o igual a 12, repite:");
		} else {
			break;
		}
	} while(1);
}</code></pre>

<p>Te habrás fijado que el valor <code>12</code> aparece escrito a mano cuatro veces. El día que queramos permitir 14 elementos nos tocará cambiarlo las cuatro veces.</p>

<p>Este caso es muy simple, la repetición de valores (al igual que en CSS pasa con los colores, tamaños&#8230;), y se puede solucionar con una constante:</p>

<pre data-language="c"><code>#define DIM 12
int main(void) {
	// Lo ideal sería que la array en este caso fuera dinámica, pero es un ejemplo...
	int vector[DIM];
	size_t length;
	printf("Introduce cuántos números vas a meter (máximo %d):", DIM);
	do {
		scanf("%u", &length);
		if ( length &gt; DIM ) {
			printf("Dimensión nó válida, ha de ser menor o igual a %d, repite:", DIM);
		} else {
			break;
		}
	} while(1);
}</code></pre>

<h4>A lo que voy</h4>
<p>Estoy oxidado con esto de escribir y me voy por las ramas&#8230;</p>
<p>Todos los lenguajes de programación tienen formas de no repetir instrucciones y valores: <strong>constantes</strong>, <strong>variables</strong>, <strong>funciones</strong>, <strong>clases</strong>&#8230; Como programador debes de tratar de abstraerte lo máximo posible para que tu código sea mucho más polivalente y legible.</p>

<h3>Separa y reutiliza</h3>
<p>Cuando me encuentro con el código fuente de úna página/aplicación y me doy de bruces con un archivo de 2000 líneas de texto, no puedo hacer otra cosa que llorar&#8230;</p>
<p>Por tu bien y el del resto de personas que lean tu código, lo mejor que puedes hacer es <strong>separar tu lógica de tu ejecución</strong>. Así, podrás <strong>reutilizar</strong> tu código lógico, y tu código principal, el de ejecución, será mucho más visible y legible.</p>

<h3>Llama a tus variables con nombres descriptivos</h3>

<p>Cuando digo variables también digo funciones/clases/constantes&#8230;</p>

<p>No hay nada como encontrarse un código así:</p>

<pre data-language="php"><code>function at($array) {
	foreach($array as $i) {
		// ...
	}
}</code></pre>

<p>No cuesta nada poner nombres descriptivos a las variables para así facilitar al que lo lee su comprensión:</p>
<pre data-language="php"><code>function purchase($products) {
	foreach($products as $product) {
		// ...
	}
}</code></pre>

<h3>Indenta tu código</h3>
<p>Sea cual sea la forma que escojas para indentar (tabulación, 2 espacios, 4 espacios&#8230;), úsala, y sobre todo sé consistente.</p>

<h2>Documentación</h2>
<p>Es muy importante saber el uso que hay que darle a un método/función, o lo que almacena una variable. Esto es incluso más importante en los lenguajes con tipos de datos dinámicos (JavaScript/PHP&#8230;).</p>

<p>Por lo general no debería ser necesario leer toda la función interna para saber qué tenemos que pasar:</p>

<pre><code>var sendGetRequest = function(url, params, callback) {
	var xhr = new XMLHttpRequest();
	// ...
}</code></pre>

<p>Deberíamos pasar un objeto a params? O tal vez valga sólo con pasar la query string via una cadena? Tal vez soporte ambas?</p>

<pre data-language="javascript"><code>/**
 * Sends an ajax GET request to a url
 * @param {String} url the target url
 * @param {Object|String} params the GET parameters either in string ("a=1&b=3") or object format ({a: 1, b: 3})
 * @param {Function} callback the success callback
 * @return {XMLHttpRequest}
 */
var sendGetRequest = function(url, params, callback) {
	var xhr = new XMLHttpRequest();
	// ...
	return xhr;
}</code></pre>

<h2>No dejes lugar a la duda!</h2>
<p>Soy de esos a los que no les gusta ver código en C/JavaScript/PHP/cualquierlenguajedondelasllavesseanopcionales escrito de esta manera:</p>
<pre data-language="c"><code>if( a == 5 )
	c = 2;
	b = 2;</code></pre>

<p>Es posible que el que programó eso fuera consciente de que la variable b es independiente de la condición (y se hubiera equivocado al indentar), pero también es posible que quisiera decir:</p>

<pre data-language="c"><code>if( a == 5 ) {
	c = 2;
	b = 2;
}</code></pre>

<p>A mí este tipo de confusiones no me gusta (pasa lo mismo cuando falta un <code>break</code> en un <code>switch</code>), y por eso no me gusta dejarme una sóla llave por poner.</p>

<h2>Ésto es todo? No</h2>
<p>Estoy seguro de que se me ha pasado alguna cosa, de ser así la pondré cuando me acuerde (con esta memoria&#8230; <i class="icon guino"></i>). <strong>Si tenéis alguna aportación es siempre bienvenida</strong>, por mí no os cortéis <i class="icon sonrisa"></i></p><p>The post <a href="https://emiliocobos.net/conceptos-basicos-de-programacion/">Conceptos básicos de programación independientes del lenguaje</a> first appeared on <a href="https://emiliocobos.net">Emilio Cobos</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://emiliocobos.net/conceptos-basicos-de-programacion/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Script para cumplir la ley de cookies</title>
		<link>https://emiliocobos.net/script-ley-de-cookies/</link>
					<comments>https://emiliocobos.net/script-ley-de-cookies/#comments</comments>
		
		<dc:creator><![CDATA[Emilio Cobos Álvarez]]></dc:creator>
		<pubDate>Tue, 17 Sep 2013 15:55:12 +0000</pubDate>
				<category><![CDATA[Javascript]]></category>
		<guid isPermaLink="false">http://emiliocobos.net/?p=734</guid>

					<description><![CDATA[<p>He desarrollado un pequeño script para poder cumplir la ley de cookies, que es apto para todos los servicios. Toda la información y demás está en Github, haré un artículo&#8230; <a class="jump-link" href="https://emiliocobos.net/script-ley-de-cookies/">Leer más <span class="meta-nav">&#187;</span></a></p>
<p>The post <a href="https://emiliocobos.net/script-ley-de-cookies/">Script para cumplir la ley de cookies</a> first appeared on <a href="https://emiliocobos.net">Emilio Cobos</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>He desarrollado un pequeño script para poder cumplir la ley de cookies, que es apto para todos los servicios. Toda la información y demás está en Github, haré un artículo más grande para que cualquiera pueda usarlo ya use blogger, wordpress o cualquier otro CMS.</p>

<p><strong>Raciona automáticamente las cookies de Analytics y Adsense</strong>, pero es sencillo añadir otros servicios de terceros sin tocar el código, posee una API de eventos para poder añadir esos scripts asíncronamente.</p>

<p style='text-align: center;'><a href="//emiliocobos.net/demos/cookietool/demo/" target="_blank" title="Link a la demo" class="boton">Demo</a> <a download href="https://github.com/ecoal95/CookieTool/archive/master.zip" target="_blank" title="Link de descarga" class="boton">Descarga</a> <a href="https://github.com/ecoal95/CookieTool" target="_blank" title="Ver en Github" class="boton">Ver en GitHub</a></p>

<h2>Características</h2>

<ul>
<li>Carga automática de Google Analytics y Google Adsense si son usados</li>
<li>API de eventos para facilitar la carga de cualquier script que cargue cookies</li>
<li>Sección de opciones</li>
</ul>

<h2>Instalación</h2>

<h3>Paso 1: Añadir el script</h3>

<p>Lo primero será añadir el script y los estilos necesarios. Los estilos son algo muy básico símplemente para asegurar que el mensaje sea visible y podéis modificarlos a vuestro gusto. Los links que veréis aquí están hosteados en github, pero lo ideal sería que cada uno guardase una copia y lo hosteara.</p>

<p>Encima de <code>&lt;/head&gt;</code>:</p>

<pre data-language="html"><code>&lt;link rel="stylesheet" type="text/css" href="https://raw.github.com/ecoal95/CookieTool/master/cookietool.css" /&gt;</code></pre>

<p>Encima de <code>&lt;/body&gt;</code> (éste es el interesante).</p>

<pre data-language="html"><code>&lt;script src="https://raw.github.com/ecoal95/CookieTool/master/cookietool.js"&gt;&lt;/script&gt;
&lt;!-- Configuración (ver más abajo) --&gt;
&lt;!-- Otros códigos de configuración (ver más abajo) --&gt;
&lt;script&gt;CookieTool.API.ask();&lt;/script&gt;</code></pre>

<h4>Uso Blogger</h4>

<p>En este caso tendrás que sustituir las comillas dobles por simples.</p>

<h4>Uso WordPress</h4>

<p>Tendrás que tocar los archivos <code>header.php</code> y <code>footer.php</code> de tu tema. Es posible que haga un plugin, pero por ahora es lo que hay.</p>

<p><strong>Si tienes las estadísticas de JetPack</strong> activadas tendrás que desactivarlas, ya que esa cookie la manda el servidor y no se puede hacer nada para evitarlo.</p>

<h3>Paso 2: Configurar el script</h3>

<p>El script admite algunas opciones para mostrar el mensaje y demás. Justo en el comentario de <em>Configuración</em> es donde debemos ponerlo.</p>

<p>Este es un ejemplo con las opciones más básicas:</p>

<pre data-language="html"><code>&lt;script&gt;
    CookieTool.Config.set('link','/politicadecookies.html'); // Link a la política de cookies
    CookieTool.Config.set('message', 'Este es el mensaje que se mostrará, &lt;a href="{{link}}"&gt;política de cookies&lt;/a&gt;');
    CookieTool.Config.set('agreetext','Sí, acepto'); // Mensaje del botón de aceptar
    CookieTool.Config.set('declinetext','No, me niego'); // Mensaje del botón de No aceptar
    CookieTool.Config.set('position', 'top'); // top o bottom, la posición del mensaje usando los estilos por defecto.

// También podríamos hacer:
CookieTool.Config.set({
    'link': '/loquesea',
    'message': 'Cualquier cosa'
    // ...
})

&lt;/script&gt;</code></pre>

<h3>Paso 3: Modificar el código que inserte cookies</h3>

<p>Aquí viene cómo modificar los códigos de Analytics y Google Adsense, que son los códigos más frecuentes y los que trata el script por defecto.</p>

<h4>Google Adsense</h4>

<p>Tendréis que usar el código asíncrono de Google Adsense con una pequeña modificación (<a href="http://emiliocobos.net/ley-de-cookies-y-adsense/" target="_blank">aquí</a> viene explicado).</p>

<h4>Google Analytics</h4>

<p>Tendréis que dejarlo tal y como está, pero sin cargar el script:</p>

<h5>Código antiguo (<code>_gaq</code>)</h5>
<p>Con dejarlo así vale</p>
<pre data-language="html"><code>&lt;script type="text/javascript"&gt;

  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-XXXXX-Y']);
  _gaq.push(['_trackPageview']);
&lt;/script&gt;</code></pre>

<h5>Código nuevo (<code>isogram</code>)</h5>

<p>En este caso el código que carga el script es un poco más difícil de quitar. Sólo hay que quitar el fragmento que va desde <code>1*new Date()</code> al fin de la función (<code>})(window...)</code>).</p>

<pre data-language="html"><code>
&lt;script&gt;
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

  ga('create', 'UA-27809661-2', 'emiliocobos.net');
  ga('send', 'pageview');

&lt;/script&gt;
</code></pre>

<h4>Otros scripts</h4>

<p>Para usar otros scripts tendréis que alterar el código de tal manera que no inserte cookies de primeras, luego podéis usar el script tal que así (en <em>otros códigos de configuración</em>):</p>

<pre data-language="html"><code>&lt;script&gt;
    CookieTool.Event.on('agree', function() {
        // Código que carga las cookies
        // Por elemplo:
        // CookieTool.Utils.loadScript('http://abc.com/script-que-carga-cookies.js');
    });
    CookieTool.Event.on('decline', function() {
        // Borrar las cookies si es posible:
        // CookieTool.Cookie.remove('cookieinsertadaporeseprograma');
    });
&lt;/script&gt;</code></pre>

<h3>Paso 3: Crear o modificar la página de Política de cookies</h3>

<p>Como habéis visto, hay una opción llamada link que lleva a una página (exigida por la ley) llamada política de cookies.</p>

<p>En esa página debéis de explicar qué es una cookie, qué cookies no requeridas instaláis y su finalidad.</p>

<p>Como la herramienta genera una cookie requerida no hará falta añadirla, pero tendréis que añadir una sección llamada <strong>Configuración de cookies</strong>, donde tenéis que poner el siguiente código html:</p>

<pre data-language="html"><code>&lt;div id="cookietool-settings"&gt;&lt;/div&gt;</code></pre>

<p>Allí se mostrará una pequeña configuración como <a href="//emiliocobos.net/demos/cookietool/demo/cookies.html" target="_blank">en la demo</a>.</p>

<h3>Ya!</h3>

<p>Pues eso, que ya tendrías tu página acorde a esa salvajada llamada ley de cookies del estado español.</p>

<h2>Modificaciones, etc&#8230;</h2>

<p>Es código libre, así que podéis tocar y cambiar lo que queráis. Cualquier mejora os rogaría que la mandarais a <a href="https://github.com/ecoal95/CookieTool">github</a></p>

<p style='text-align: center;'><a href="//emiliocobos.net/demos/cookietool/demo/" target="_blank" title="Link a la demo" class="boton">Demo</a> <a download href="https://github.com/ecoal95/CookieTool/archive/master.zip" target="_blank" title="Link de descarga" class="boton">Descarga</a> <a href="https://github.com/ecoal95/CookieTool" target="_blank" title="Ver en Github" class="boton">Ver en GitHub</a></p>

<h2>Tú lo has hecho, por qué no lo usas?</h2>

<p>Sí lo uso, pero lo uso de un modo «especial»: Yo asumo que vosotros dais el consentimiento, ya que la falta de consentimiento no está tipificada como delito (<a href="http://noticias.juridicas.com/base_datos/Admin/l34-2002.t7.html#a38">ver aquí</a>), así que no puede ser sancionada, sin embargo, sí informo y doy opciones para revocar el permiso en mi página de <a href="http://emiliocobos.net/cookies/" title="Política de cookies">política de cookies</a>.</p>

<p>Si os interesa usarlo así, sólo hace falta cambiar el <code>CookieTool.API.ask()</code> por <code>CookieTool.API.impliedAgreement()</code></p><p>The post <a href="https://emiliocobos.net/script-ley-de-cookies/">Script para cumplir la ley de cookies</a> first appeared on <a href="https://emiliocobos.net">Emilio Cobos</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://emiliocobos.net/script-ley-de-cookies/feed/</wfw:commentRss>
			<slash:comments>59</slash:comments>
		
		
			</item>
		<item>
		<title>Ley de cookies española y adsense</title>
		<link>https://emiliocobos.net/ley-de-cookies-y-adsense/</link>
					<comments>https://emiliocobos.net/ley-de-cookies-y-adsense/#comments</comments>
		
		<dc:creator><![CDATA[Emilio Cobos Álvarez]]></dc:creator>
		<pubDate>Tue, 17 Sep 2013 15:54:54 +0000</pubDate>
				<category><![CDATA[Web]]></category>
		<guid isPermaLink="false">http://emiliocobos.net/?p=732</guid>

					<description><![CDATA[<p>Estos días ha habido mucho revuelo sobre la ley de cookies, y cómo nos afecta a los residentes en españa como publicadores. Personalmente creo que esta ley es completamente innecesaria,&#8230; <a class="jump-link" href="https://emiliocobos.net/ley-de-cookies-y-adsense/">Leer más <span class="meta-nav">&#187;</span></a></p>
<p>The post <a href="https://emiliocobos.net/ley-de-cookies-y-adsense/">Ley de cookies española y adsense</a> first appeared on <a href="https://emiliocobos.net">Emilio Cobos</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>Estos días ha habido mucho revuelo sobre la <strong>ley de cookies</strong>, y cómo nos afecta a los residentes en españa como publicadores.</p>

<p>Personalmente creo que esta ley es completamente innecesaria, es sobrecomplicar las cosas sin ningún motivo: <strong>las cookies en el 99% de los sitios web sólo son usadas para mejorar la experiencia del usuario</strong>. Pero qué se le va a hacer&#8230;</p>

<h2>Google Adsense</h2>

<p>El caso es que he estado enredando estos días con adsense (que usa cookies), y me estaba preguntando cómo podíamos cargar adsense una vez el usuario diera el visto bueno. El código de adsense (el de toda la vida, el síncrono, y el único que yo conocía) es algo así:</p>

<pre data-language="html"><code>&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "ca-pub-xxxxxxxxxxx";
/* nombre del anuncio */
google_ad_slot = "xxxxxxxxx";
google_ad_width = xxx;
google_ad_height = xxx;
//--&gt;
&lt;/script&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;</code></pre>

<p>Éste código <strong>no se puede cambiar</strong>, la única forma de insertarlo automáticamente podría ser <strong>un iframe que contuviera los anuncios</strong>, pero <strong>el robot de Google Adsense no rastrearía nuestra página, sino esa página en blanco</strong>. Por desgracia no es viable.</p>

<h3>Entonces, ¿Cómo puedo cumplir la ley si uso Google Adsense?</h3>

<p>Gracias a que a google le ha dado por crear un nuevo tipo de código (el código asíncrono), podemos crear fácilmente los anuncios y sólo mostrarlos cuando queramos cargando el script.</p>

<h3>Pero a Google no le gusta que toquen su código&#8230;</h3>

<p>Es cierto, a mucha gente le han baneado cuentas de Adsense con el pretexto de que el código en la página no era exactamente como debería ser. 
Últimamente han sido más permisivos, y daban permiso para modificarlo si era para un diseño responsive, un A/B test, etc&#8230; (<a target="_blank" href="https://support.google.com/adsense/answer/1354736?hl=es">Ver aquí</a>).</p>

<p>La modificación que yo propongo (eliminar el script del código asíncrono, para cargarlo tras el consentimiento del usuario) no está listada explícitamente ahí, pero entra dentro de «modificaciones aceptables». Además sí que lo está implícitamente (tercera pregunta frecuente).</p>

<h2>Al meollo: ¿Cuál es la idea?</h2>

<p>Básicamente, sustituir todos los anuncios por anuncios asíncronos, y eliminar el script, quedando así: </p>

<pre data-language="html"><code>&lt;!-- nombre del anuncio --&gt;
&lt;ins class="adsbygoogle"
     style="display:inline-block;width:xxxpx;height:xxxpx"
     data-ad-client="ca-pub-xxxxxxxxxxxxxx"
     data-ad-slot="xxxxxxx"&gt;&lt;/ins&gt;
&lt;script&gt;
(adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;</code></pre>

<h3>¿Y los anuncios sin tamaño fijo (adaptable)?</h3>

<p>Usan el código asíncrono, así que lo mismo, sólo hay que quitar el primer <code>&lt;script&gt;</code>.</p>

<p><strong>Cuando el usuario de su consentimiento se carga el script mediante javascript</strong> (publicaré los detalles junto con una herramienta para hacerlo en otro artículo, probablemente a la vez que este, si me acuerdo dejo el link ;)).</p>

<h4>Actualización: Script para cumplir la ley de cokies</h4>

<p>Pues eso, que ya terminé el script, podéis verlo <a href="http://emiliocobos.net/script-ley-de-cookies/" title="Script para cumplir la ley de cookies">aquí</a>.</p><p>The post <a href="https://emiliocobos.net/ley-de-cookies-y-adsense/">Ley de cookies española y adsense</a> first appeared on <a href="https://emiliocobos.net">Emilio Cobos</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://emiliocobos.net/ley-de-cookies-y-adsense/feed/</wfw:commentRss>
			<slash:comments>7</slash:comments>
		
		
			</item>
		<item>
		<title>Buscar tweets con PHP (Twitter API 1.1)</title>
		<link>https://emiliocobos.net/buscar-tweets-con-php/</link>
					<comments>https://emiliocobos.net/buscar-tweets-con-php/#comments</comments>
		
		<dc:creator><![CDATA[Emilio Cobos Álvarez]]></dc:creator>
		<pubDate>Thu, 05 Sep 2013 22:32:12 +0000</pubDate>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Twiter API]]></category>
		<guid isPermaLink="false">http://emiliocobos.net/?p=720</guid>

					<description><![CDATA[<p>Buff, llevaba mucho sin escribir. Lo cierto es que no por gusto (preparar la selectividad, problemas familiares y mononucleosis es un combo letal), pero bueno, lo importante es que ya&#8230; <a class="jump-link" href="https://emiliocobos.net/buscar-tweets-con-php/">Leer más <span class="meta-nav">&#187;</span></a></p>
<p>The post <a href="https://emiliocobos.net/buscar-tweets-con-php/">Buscar tweets con PHP (Twitter API 1.1)</a> first appeared on <a href="https://emiliocobos.net">Emilio Cobos</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>Buff, llevaba mucho sin escribir. Lo cierto es que no por gusto (preparar la selectividad, problemas familiares y mononucleosis es un combo letal), pero bueno, lo importante es que <strong>ya estoy de vuelta</strong>, y tengo algunas cosillas que me gustaría presentar pronto por aquí (¿alguien ha dicho algo de una <strong>CMS super ligera</strong>? <i class="icon guino">;)</i>).</p>

<p style='text-align: center;'><a href="/demos/buscatweets" target="_blank" title="Link a la demo" class="boton">Demo</a> <a download href="/demos/buscatweets/buscatweets.zip" target="_blank" title="Link de descarga" class="boton">Descarga</a> </p>

<p>Bueno, lo que vamos a hacer hoy es <strong>buscar tweets con PHP</strong>. Twitter nos provee con una <a href="https://dev.twitter.com/docs/api">API</a> bastante chula, pero por desgracia la autenticación con ella, que se realiza mediante OAuth, es bastante complicada.</p>

<p>Por ello vamos a usar una librería muy bien mantenida llamada <a href="https://github.com/abraham/twitteroauth">TwitterOAuth</a>, que nos facilitará la tarea de hacer las solicitudes a la API.</p>

<p>Lo que haremos por ahora será crear nuestro index.php, una carpeta llamada <code>inc</code>, donde meteremos <code>OAuth.php</code>, <code>twitteroauth.php</code>, <code>Cache.php</code> (<a href="http://emiliocobos.net/php-cache/" title="Implementar un sistema de caché simple en PHP">éste archivo</a>) y otros archivos que puedan surgir mientras lo hacemos, otra carpeta llamada <code>cache</code> donde almacenaremos las búsquedas, y una última carpeta llamada <code>css</code> para nuestro archivo <code>style.css</code> (yo personalmente lo generaré con <a href="http://emiliocobos.net/preprocesar-css-instalando-sass-y/" title="Preprocesar CSS: Instalando SASS y Compass">compass</a>).</p>

<p>Ya tenemos todo preparado, <strong>empecemos</strong>!</p>

<h3>Paso 1: Crear nuestra aplicación</h3>
<p>Lo primero que tendremos que hacer es ir a <a href="https://dev.twitter.com/" target="_blank">Twitter Developers</a> e iniciar sesión.</p>

<p>En el desplegable de nuestra foto, hacemos click en <strong>My Applications</strong> &raquo; <strong>Create a new aplication</strong>. Insertamos el nombre de nuestra aplicación, la descripción y la página en la que va a estar, rellenamos el captcha, y listo!</p>

<figure id="attachment_725" class="post-caption alignnone" style="width: 991px;"><a href="http://emiliocobos.net/wp-content/uploads/2013/09/Buscatweets-crearapp.png"><img decoding="async" loading="lazy" src="http://emiliocobos.net/wp-content/uploads/2013/09/Buscatweets-crearapp.png" alt="Desplegable para crear una app" width="991" height="143" class="size-full wp-image-725" srcset="https://emiliocobos.net/wp-content/uploads/2013/09/Buscatweets-crearapp.png 991w, https://emiliocobos.net/wp-content/uploads/2013/09/Buscatweets-crearapp-300x43.png 300w" sizes="(max-width: 991px) 100vw, 991px" /></a><figcaption class="wp-caption-text">Crear app</figcaption></figure>

<p>Aparecerá la página de la aplicación, donde tenemos el consumer key y el consumer secret:</p>

<figure id="attachment_724" class="post-caption alignnone" style="width: 574px;"><a href="http://emiliocobos.net/wp-content/uploads/2013/09/Buscatweets-key-secret.png"><img decoding="async" loading="lazy" src="http://emiliocobos.net/wp-content/uploads/2013/09/Buscatweets-key-secret.png" alt="Consumer keys y consumer secret" width="574" height="69" class="size-full wp-image-724" srcset="https://emiliocobos.net/wp-content/uploads/2013/09/Buscatweets-key-secret.png 574w, https://emiliocobos.net/wp-content/uploads/2013/09/Buscatweets-key-secret-300x36.png 300w" sizes="(max-width: 574px) 100vw, 574px" /></a><figcaption class="wp-caption-text">Consumer keys y consumer secret</figcaption></figure>

<h3>Paso 2: Crear nuestro token de usuario</h3>
<p>Para hacer solicitudes a la API necesitamos el token de usuario y el token secret que podemos generar directamente pulsando el botón <strong>Create my access token</strong>. Con ello ya tenemos todos los datos necesarios para hacer solicitudes a la api.</p>

<a href="http://emiliocobos.net/wp-content/uploads/2013/09/Buscatweets-token.png"><img decoding="async" loading="lazy" src="http://emiliocobos.net/wp-content/uploads/2013/09/Buscatweets-token.png" alt="Crear access token" width="964" height="125" class="alignnone size-full wp-image-723" srcset="https://emiliocobos.net/wp-content/uploads/2013/09/Buscatweets-token.png 964w, https://emiliocobos.net/wp-content/uploads/2013/09/Buscatweets-token-300x38.png 300w" sizes="(max-width: 964px) 100vw, 964px" /></a>

<h3>Paso 3: El index.php</h3>
<p>Puedes ver el pequeño formulario descargando el código algo más abajo, pero las líneas relevantes del código son éstas:</p>
<pre data-language="php"><code>$twitteroauth = new TwitterOAuth(APP_CONSUMER_KEY, APP_CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET);
$results = $twitteroauth->get('search/tweets', array(
	'q' => $_GET['q'],
	'lang' => 'es',
	'count' => 5,
	'include_entities' => false,
));</code></pre>

<p>Ésto nos devolverá un objeto <code>stdClass</code>, donde los tweets se guardan en la propiedad <code>statuses</code></p>

<p>Listo! Ahora ya solo falta mostrarlos a nuestro gusto usando las propiedades adecuadas. Puedes descargar los archivos para ver qué propiedades he usado yo, o ver la demo directamente</p>

<p style='text-align: center;'><a href="/demos/buscatweets" target="_blank" title="Link a la demo" class="boton">Demo</a> <a download href="/demos/buscatweets/buscatweets.zip" target="_blank" title="Link de descarga" class="boton">Descarga</a> </p><p>The post <a href="https://emiliocobos.net/buscar-tweets-con-php/">Buscar tweets con PHP (Twitter API 1.1)</a> first appeared on <a href="https://emiliocobos.net">Emilio Cobos</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://emiliocobos.net/buscar-tweets-con-php/feed/</wfw:commentRss>
			<slash:comments>23</slash:comments>
		
		
			</item>
		<item>
		<title>Creando el .htaccess perfecto</title>
		<link>https://emiliocobos.net/creando-el-htaccess-perfecto/</link>
					<comments>https://emiliocobos.net/creando-el-htaccess-perfecto/#comments</comments>
		
		<dc:creator><![CDATA[Emilio Cobos Álvarez]]></dc:creator>
		<pubDate>Mon, 22 Apr 2013 00:30:40 +0000</pubDate>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[.htaccess]]></category>
		<guid isPermaLink="false">http://emiliocobos.net/?p=700</guid>

					<description><![CDATA[<p>.htaccess es un archivo de configuración de Apache, que nos permite establecer reglas en un directorio. De él puede depender una buena parte del rendimiento de nuestras páginas web. En&#8230; <a class="jump-link" href="https://emiliocobos.net/creando-el-htaccess-perfecto/">Leer más <span class="meta-nav">&#187;</span></a></p>
<p>The post <a href="https://emiliocobos.net/creando-el-htaccess-perfecto/">Creando el .htaccess perfecto</a> first appeared on <a href="https://emiliocobos.net">Emilio Cobos</a>.</p>]]></description>
										<content:encoded><![CDATA[<p><code>.htaccess</code> es un archivo de configuración de Apache, que nos permite establecer reglas en un directorio. De él puede depender una buena parte del rendimiento de nuestras páginas web.</p>

<p>En este artículo os voy a enseñar mis <strong>líneas de .htaccess básicas para cualquier página web</strong>.</p>

<h2>Nota inicial</h2>
<p><code>.htaccess</code> <strong>se evalúa cada solicitud</strong>, añadiendo carga al servidor. Por eso, siempre que sea posible, en producción modifica el archivo <code>httpd.conf</code> directamente.</p>

<p>Desgraciadamente, esto no es posible para la inmensa mayoría de los mortales (entre los que me incluyo).</p>

<p>Finalmente indicar que buena parte de estas líneas de código vienen gracias a <a target="_blank" href="http://html5boilerplate.com/">html5 Boilerplate</a>. Creo que recopilarlos aquí y hacerlos accesibles a todos puede ser una buena idea.</p>

<h2>Redirección del domino</h2>

<p>Hay dos opciones: Que quieras redirigir el dominio <strong>con www a sin www</strong> (de www.midominio.com a midominio.com) o viceversa. Mantener ambos puede llevar problemas de SEO, o acceso a archivos.</p>

<h3>De con www a sin www</h3>

<div class="important-note">Tened en cuenta que hace falta activar <code>RewriteEngine</code> para que ambos funcionen con la línea <code>RewriteEngine On</code> si no está activado por defecto</div>

<pre data-nohighlight data-language="htaccess"><code># Eliminar www.
&lt;IfModule mod_rewrite.c&gt;
  RewriteCond %{HTTPS} !=on
  RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
  RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]
&lt;/IfModule&gt;</code></pre>

<h3>De sin www a con www</h3>
<pre data-nohighlight data-language="htaccess"><code>&lt;IfModule mod_rewrite.c&gt;
  RewriteCond %{HTTPS} !=on
  RewriteCond %{HTTP_HOST} !^www\..+$ [NC]
  RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
&lt;/IfModule&gt;</code></pre>

<h2>Caché de archivos</h2>
<p>La caché de archivos puede ser inmensamente beneficiosa para la velocidad de una web. Básicamente: Si un usuario visita cinco páginas de nuestra web, no tiene por qué descargar los mismos archivos estáticos (como imágenes, css y javascript) cinco veces. El navegador <strong>puede almacenar esos archivos en el sistema</strong> para obtenerlos mucho más rápidamente, pero para ello <strong>necesita instrucciones del servidor</strong>.</p>

<pre data-nohighlight data-language="htaccess"><code>&lt;IfModule mod_expires.c&gt;
  ExpiresActive on

  # Por defecto 1 mes de caché
  ExpiresDefault                          "access plus 1 month"

  # los manifiestos appcache necesitan solicitarse cada vez, por firefox 3.6 (probablemente no necesario actualmente?
  ExpiresByType text/cache-manifest       "access plus 0 seconds"

  # El HTML nunca debe de ser cacheado
  ExpiresByType text/html                 "access plus 0 seconds"

  # Los datos dinámicos tampoco (tal vez podría variar dependiendo de tu aplicación)
  ExpiresByType text/xml                  "access plus 0 seconds"
  ExpiresByType application/xml           "access plus 0 seconds"
  ExpiresByType application/json          "access plus 0 seconds"

  # Una hora para los feeds (cambiar dependiendo de la fecha de actualización de tu web)
  ExpiresByType application/rss+xml       "access plus 1 hour"
  ExpiresByType application/atom+xml      "access plus 1 hour"

  # Favicon (Sólo una semana porque el nombre no cambia, luego podría haber cambios y mantenerse el cacheado)
  ExpiresByType image/x-icon              "access plus 1 week"

  # Imágenes, vídeo, audio: 1 mes
  ExpiresByType image/gif                 "access plus 1 month"
  ExpiresByType image/png                 "access plus 1 month"
  ExpiresByType image/jpeg                "access plus 1 month"
  ExpiresByType video/ogg                 "access plus 1 month"
  ExpiresByType audio/ogg                 "access plus 1 month"
  ExpiresByType video/mp4                 "access plus 1 month"
  ExpiresByType video/webm                "access plus 1 month"

  # Fuentes web: 1 mes
  ExpiresByType application/x-font-ttf    "access plus 1 month"
  ExpiresByType font/opentype             "access plus 1 month"
  ExpiresByType application/x-font-woff   "access plus 1 month"
  ExpiresByType image/svg+xml             "access plus 1 month"
  ExpiresByType application/vnd.ms-fontobject "access plus 1 month"

  # CSS y JavaScript: 1 año. Ten en cuenta que si cambias los ficheros deberías usar una query string o un nombre de archivo diferente para evitar que los visitantes reciban archivos cacheados.
  ExpiresByType text/css                  "access plus 1 year"
  ExpiresByType application/javascript    "access plus 1 year"

&lt;/IfModule&gt;

# Eliminar E-Tag
# Estamos enviando periodos de caché muy amplios, así que no es necesario que el navegador compruebe mediante E-Tag si el fichero cambió
&lt;IfModule mod_headers.c&gt;
  Header unset ETag
&lt;/IfModule&gt;
FileETag None</code></pre>

<h2>Compresión GZIP</h2>
<p>GZIP es la manera más rápida de reducir el tamaño del archivo enviado al navegador, mejorando el tiempo de carga. Con las siguientes líneas la activarás en tu web:</p>
<pre data-nohighlight data-language="htaccess"><code>
&lt;IfModule mod_deflate.c&gt;
    # Force compression for mangled headers.
    # http://developer.yahoo.com/blogs/ydn/posts/2010/12/pushing-beyond-gzipping
    &lt;IfModule mod_setenvif.c&gt;
        &lt;IfModule mod_headers.c&gt;
            SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding
            RequestHeader append Accept-Encoding &quot;gzip,deflate&quot; env=HAVE_Accept-Encoding
        &lt;/IfModule&gt;
    &lt;/IfModule&gt;

    &lt;IfModule mod_filter.c&gt;
        AddOutputFilterByType DEFLATE application/atom+xml \
                                      application/javascript \
                                      application/json \
                                      application/rss+xml \
                                      application/vnd.ms-fontobject \
                                      application/x-font-ttf \
                                      application/x-web-app-manifest+json \
                                      application/xhtml+xml \
                                      application/xml \
                                      font/opentype \
                                      image/svg+xml \
                                      image/x-icon \
                                      text/css \
                                      text/html \
                                      text/plain \
                                      text/x-component \
                                      text/xml
    &lt;/IfModule&gt;

&lt;/IfModule&gt;</code></pre>

<h2>Codificación UTF-8</h2>

<p>Si alguna vez habéis tenido problemas con caracteres extraños en vuestro servidor, puede ser por dos cosas: La base de datos o el propio servidor, si es por lo segundo, con las siguientes líneas debería de estar solucionado:</p>

<pre data-nohighlight data-language="htaccess"><code>AddDefaultCharset utf-8
AddCharset utf-8 .atom .css .js .json .rss .vtt .xml</code></pre>

<h2>Forzar IE a no emularse</h2>

<p>Puede que la conozcáis o no, pero hay una pequeña cabecera usada por IE llamada <code>X-UA-Compatible</code>, que puede hacer que IE9 se comporte como si fuera IE7 (por ejemplo). Esto causa bastantes problemas, porque además de usar un navegador menos compilante con los estándares, crea inconsistencias entre versiones, para asegurarse de que IE10 actúa como IE10, IE9 como IE9, etc&#8230; y que IE6/7/8 usen Chrome Frame si está instalado:</p>

<pre data-nohighlight data-language="htaccess"><code># Eliminar www.
&lt;IfModule mod_headers.c&gt;
    Header set X-UA-Compatible "IE=edge,chrome=1"
    # Sólo queremos añadirlo para páginas HTML, el resto es un desperdicio de ancho de banda
    &lt;FilesMatch "\.(appcache|crx|css|eot|gif|htc|ico|jpe?g|js|m4a|m4v|manifest|mp4|oex|oga|ogg|ogv|otf|pdf|png|safariextz|svg|svgz|ttf|vcf|webapp|webm|webp|woff|xml|xpi)$"&gt;
        Header unset X-UA-Compatible
    &lt;/FilesMatch&gt;
&lt;/IfModule&gt;</code></pre>

<h2>¿Alguna línea de código más?</h2>
<p>Soy todo oídos si tienes algo que aportar :)</p><p>The post <a href="https://emiliocobos.net/creando-el-htaccess-perfecto/">Creando el .htaccess perfecto</a> first appeared on <a href="https://emiliocobos.net">Emilio Cobos</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://emiliocobos.net/creando-el-htaccess-perfecto/feed/</wfw:commentRss>
			<slash:comments>86</slash:comments>
		
		
			</item>
		<item>
		<title>Polyfill para input type time &#8211; TimePikr</title>
		<link>https://emiliocobos.net/polyfill-input-type-time/</link>
					<comments>https://emiliocobos.net/polyfill-input-type-time/#comments</comments>
		
		<dc:creator><![CDATA[Emilio Cobos Álvarez]]></dc:creator>
		<pubDate>Tue, 09 Apr 2013 21:16:49 +0000</pubDate>
				<category><![CDATA[Javascript]]></category>
		<guid isPermaLink="false">http://emiliocobos.net/?p=694</guid>

					<description><![CDATA[<p>Bueno, siento haber dejado de publicar tanto, pero por razones de tiempo (odio segundo de bachillerato ;)) no he podido. Ésto es simplemente la presentación oficial de un script que&#8230; <a class="jump-link" href="https://emiliocobos.net/polyfill-input-type-time/">Leer más <span class="meta-nav">&#187;</span></a></p>
<p>The post <a href="https://emiliocobos.net/polyfill-input-type-time/">Polyfill para input type time – TimePikr</a> first appeared on <a href="https://emiliocobos.net">Emilio Cobos</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>Bueno, siento haber dejado de publicar tanto, pero por razones de tiempo (odio segundo de bachillerato <i class="icon guino">;)</i>) no he podido.</p>

<p>Ésto es simplemente la presentación <em>oficial</em> de un script que hice hace poco, para emular el funcionamiento de <code>input[type="time"]</code> en navegadores que no lo soportaran, y que puedes ver <a href="https://github.com/ecoal95/time-pollyfill">en github</a></p>

<p style='text-align: center;'><a href="/demos/timepicker/demo.html" target="_blank" title="Link a la demo" class="boton">Demo</a> <a download href="https://github.com/ecoal95/time-pollyfill/archive/master.zip" target="_blank" title="Link de descarga" class="boton">Descarga</a> <a href="https://github.com/ecoal95/time-pollyfill" target="_blank" title="Ver en Github" class="boton">Ver en GitHub</a></p>

<p>Para que os hagáis una idea, el soporte para <code>&lt;input type="time"&gt;</code> es muy escaso. Actualmente sólo Chrome y Opera.</p>

<p>El uso es sencillo, simplemente creamos una instancia del objeto (<code>TimePikr</code>), pasáis el elemento y listo! Si hay soporte nativo se deja como está. Si no hay soporte o el elemento no es del tipo esperado se aplican ciertas operaciones mágicas que&#8230;</p>

<p>No, ahora en serio, simplemente ocultamos el elemento y lo reemplazamos por un <code>input[type="text"]</code> con dos flechas y un par de eventos, que hacen el resto: <strong>validación</strong>, <strong>acceso rápido</strong>&#8230;</p>

<h2 id="uso">Uso</h2>

<p>Hace falta cargar <strong>dos archivos</strong>: el CSS (que hace que las flechitas se vean genial <i class="icon guino">;)</i>) y el Javascript. Un uso básico sería así:</p>

<pre data-language="html"><code>&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;!-- ... --&gt;
    &lt;link rel=&quot;stylesheet&quot; href=&quot;timepicker.css&quot;&gt;
    &lt;!-- ... --&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;!-- ... --&gt;
    &lt;input type=&quot;time&quot; id=&quot;timepikr-me&quot;&gt;
    &lt;!-- ... --&gt;
    &lt;script src=&quot;timepicker.js&quot;&gt;&lt;/script&gt;
    &lt;script&gt;
        var picker = new TimePikr({
            element: document.getElementById('timepikr-me');
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>

<p>Obviamente, si hay soporte nativo no son necesarios, así que&#8230; Carga condicional via <a href="http://emiliocobos.net/modernizr-uso-y-funciones/" title="Modernizr: Comprobando las capacidades del navegador">Modernizr</a> al rescate!</p>

<pre data-language="javascript"><code>Modernizr.load({
    test: Modernizr.inputtypes.time,
    nope: ['timepicker.css', 'timepicker.js'],
    callback: function() {
        var picker = new TimePikr({
            element: document.getElementById('timepikr-me');
        });
    }
})</code></pre>

<p>Espero que os sea útil :)</p><p>The post <a href="https://emiliocobos.net/polyfill-input-type-time/">Polyfill para input type time – TimePikr</a> first appeared on <a href="https://emiliocobos.net">Emilio Cobos</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://emiliocobos.net/polyfill-input-type-time/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
	</channel>
</rss>
