<?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>log</title>
	<atom:link href="http://log.pt/feed/" rel="self" type="application/rss+xml" />
	<link>http://log.pt</link>
	<description>smart software development. great user experience</description>
	<lastBuildDate>Fri, 11 May 2012 12:38:39 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
		<item>
		<title>Desenvolvimento sobre WordPress (3) &#8212; Shortcodes</title>
		<link>http://log.pt/blog/2012/03/wordpress-tutorial-shortcodes/</link>
		<comments>http://log.pt/blog/2012/03/wordpress-tutorial-shortcodes/#comments</comments>
		<pubDate>Fri, 23 Mar 2012 16:54:23 +0000</pubDate>
		<dc:creator>Luís Rodrigues</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://log.pt/?p=13542</guid>
		<description><![CDATA[Nas primeiras duas partes da nossa série de artigos introdutórios sobre desenvolvimento em WordPress, centrámo-nos na API de hooks, que serve para invocar funções que executem acções ou filtrem dados em resposta a acontecimentos na plataforma. Trataremos agora da API de shortcodes do WordPress, que permite que usemos, no conteúdo de artigos e páginas, um [...]]]></description>
			<content:encoded><![CDATA[<p>Nas <a href="http://log.pt/blog/2012/01/wordpress-tutorial-actions/">primeiras</a> <a href="http://log.pt/blog/2012/01/wordpress-tutorial-filters/">duas partes</a> da nossa série de artigos introdutórios sobre desenvolvimento em WordPress, centrámo-nos na API de <em>hooks</em>, que serve para invocar funções que executem acções ou filtrem dados em resposta a acontecimentos na plataforma.</p>
<p>Trataremos agora da API de <em>shortcodes</em> do WordPress, que permite que usemos, no conteúdo de artigos e páginas, um conjunto de códigos <a href="http://pt.wikipedia.org/wiki/Macro">macro</a> delimitados por parênteses rectos (<code>[<!-- -->]</code>) e inspirados pela linguagem de formatação <a href="http://pt.wikipedia.org/wiki/BBCode">BBCode</a>. No momento da apresentação ao visitante do site, estes macros são substituídos pelo resultado da função que abstraem.</p>
<p>O WordPress inclui de origem alguns destes <em>shortcodes</em>. Por exemplo, o <em>shortcode</em> <code>[<!-- -->gallery]</code> é substituído por uma galeria de fotografias com todas as imagens que estiverem anexadas ao artigo ou página onde se encontra. Um <em>shortcode</em> é descrito de forma muito semelhante a uma vulgar <em>tag</em> HTML, permitindo atributos e <em>tags</em> de abertura e fecho. Por exemplo, <code>[<!-- -->gallery id="3"]</code> ou <code>[<!-- -->block]Lorem ipsum[/block]</code>.</p>
<p>Para além dos <em>shortcodes</em> oferecidos pelo WordPress, tanto temas como <em>plugins</em> podem criar novos códigos. É o que iremos descobrir neste artigo.</p>
<h3 id="omeuprimeiroshortcode">O meu primeiro <em>shortcode</em></h3>
<p>Como nos artigos anteriores, concentraremos as nossas modificações no ficheiro <em>functions.php</em> do tema, situado em <em>/wp-content/themes/<strong>pasta do tema</strong>/functions.php</em>, e só mais tarde aplicaremos o conhecimento adquirido ao desenvolvimento de uma nova extensão.</p>
<p>Para criar um novo <em>shortcode</em> em código basta, muito simplesmente, declarar uma função que o implemente e associá-la ao nome pretendido com <a href="http://codex.wordpress.org/Function_Reference/add_shortcode"><code>add_shortcode()</code></a>. A forma de o fazer é semelhante ao que já fazíamos para os <em>hooks</em>:</p>
<pre class="brush: php; title: ; notranslate">
function tutorial_hello_world_shortcode ( $atts, $content = null ) {
    return 'Olá, mundo!';
}

add_shortcode( 'hello', 'tutorial_hello_world_shortcode' );
</pre>
<p>E pronto! Experimente inserir o <em>shortcode</em> <code>[<!-- -->hello]</code> no conteúdo de qualquer página ou artigo, e este será substituído pela expressão “Olá, mundo!” aquando da visualização.</p>
<h3 id="atributosdoshortcode">Atributos do <em>shortcode</em></h3>
<p>Como já demos a entender, é possível passar atributos a um <em>shortcode</em>, à semelhança do que acontece em BBCode ou em HTML. Os mais atentos terão reparado que a função <code>tutorial_hello_world_shortcode()</code> aceita um parâmetro <code>$atts</code>, que recebe precisamente um <em>array</em> de parâmetros passados no <em>shortcode</em>.</p>
<p>Não é preciso fazer nada de especial para obter estes parâmetros, já que a API do WordPress abstrai o processo de análise da <em>string</em> para recolha dos parâmetros. Um <em>shortcode</em> com o seguinte formato:</p>
<blockquote>
<pre>[<!-- -->hello name="Luís Rodrigues" other="Outro atributo"]</pre>
</blockquote>
<p>irá invocar a nossa função <code>tutorial_hello_world_shortcode()</code> com o seguinte <em>array</em> passado por parâmetro:</p>
<pre class="brush: php; title: ; notranslate">
Array
(
    [name] =&gt; Luís Rodrigues
    [other] =&gt; Outro atributo
)
</pre>
<p>Isto significa que podemos modificar a nossa função para lhe dar um toque mais pessoal:</p>
<pre class="brush: php; title: ; notranslate">
function tutorial_hello_world_shortcode ( $atts, $content = null ) {
    if (empty( $atts['name'] ))
        return 'Olá, mundo!';
    else
        return 'Olá, ' . $atts['name'] . '!';
}

add_shortcode( 'hello', 'tutorial_hello_world_shortcode' );
</pre>
<p>Assim, podemos escrever o <em>shortcode</em></p>
<blockquote>
<pre>[<!-- -->hello name="Luís Rodrigues"]</pre>
</blockquote>
<p>e obter</p>
<blockquote><p>Olá, Luís Rodrigues!</p></blockquote>
<h3 id="contedodoshortcode">Conteúdo do <em>shortcode</em></h3>
<p>O <em>shortcode</em> acima limita-se a substituir todo o código pelo retorno da função associada. Contudo, também é possível usar <em>shortcodes</em> para filtrar blocos de conteúdo sem o substituir por completo.</p>
<p>Aqui entra em palco o segundo parâmetro da nossa função, <code>$content</code>, que guarda todo o conteúdo existente entre a abertura e fecho de um <em>shortcode</em>.</p>
<pre class="brush: php; title: ; notranslate">
function tutorial_hello_world_shortcode ( $atts, $content = null ) {
    $name = empty( $atts['name'] ) ? 'mundo' : $atts['name'];
    $output = &quot;&lt;strong&gt;Olá, $name!&lt;/strong&gt; &quot;;
    if (!is_null( $content )) {
        $output .= $content;
        $output .= &quot; &lt;strong&gt;Adeus, $name!&lt;/strong&gt;&quot;;
    }
    return $output;
}

add_shortcode( 'hello', 'tutorial_hello_world_shortcode' );
</pre>
<p>A inserção do <em>shortcode</em> revisto no nosso artigo ou página poderia ter o formato</p>
<blockquote>
<pre>[<!-- -->hello name="Luís Rodrigues"]Lorem ipsum dolor sit amet...[/hello]</pre>
</blockquote>
<p>resultando em</p>
<blockquote><p><strong>Olá, Luís Rodrigues!</strong> Lorem ipsum dolor sit amet&#8230; <strong>Adeus, Luís Rodrigues!</strong></p></blockquote>
<p>A invocação anterior, contendo apenas um código <code>[<!-- -->hello]</code> simples, com o sem atributo, continuaria a funcionar da mesma forma, já que o código da nossa função verifica a existência ou não-existência do atributo <code>name</code> e do conteúdo.</p>
<h3 id="valoresporomisso">Valores por omissão</h3>
<p>No código do nosso exemplo anterior, ocorre uma verificação prévia do atributo <code>name</code> e a atribuição do valor por omissão <code>"mundo"</code> caso este não se encontre definido.</p>
<p>Há, no entanto, uma forma mais elegante e recomendada de <a href="http://codex.wordpress.org/Function_Reference/shortcode_atts">indicar os valores por omissão</a> e <a href="http://php.net/manual/en/function.extract.php">extrair os valores</a> de um conjunto de atributos. Assim, em vez de</p>
<pre class="brush: php; title: ; notranslate">
$name = empty( $atts['name'] ) ? 'mundo' : $atts['name'];
</pre>
<p>podemos escrever</p>
<pre class="brush: php; title: ; notranslate">
extract( shortcode_atts( array(
    'name' =&gt; 'mundo',
    'other' =&gt; 'XPTO' // Valor por omissão para outro atributo
), $atts ) );
</pre>
<h3 id="exemplotil">Exemplo útil</h3>
<p>Os <em>shortcodes</em> têm inúmeras aplicações práticas, uma das quais sendo a possibilidade de limitar a visualização de conteúdos tendo em conta um conjunto de condições.</p>
<p>Por exemplo, podemos criar um novo <em>shortcode</em> <code>[<!-- -->access]</code> que limite o acesso de utilizadores não-autenticados aos conteúdos delimitados pelo <em>shortcode</em>.</p>
<pre class="brush: php; title: ; notranslate">
function shortcode_access_control ( $atts, $content = null ) {
    extract( shortcode_atts( array(
        'capability' =&gt; 'read',
        'error' =&gt; 'Este conteúdo está reservado a utilizadores autenticados.',
    ), $atts ) );
    if (current_user_can( $capability ) &amp;&amp; !is_null( $content ))
        return $content;
    else
        return $error;
}

add_shortcode( 'access', 'shortcode_access_control' );
</pre>
<p>O <em>shortcode</em> pode ser invocado digitando o seguinte texto algures no conteúdo de uma página ou artigo:</p>
<blockquote>
<pre>[<!-- -->access]TOP SECRET![/access]</pre>
</blockquote>
<p>Um utilizador autenticado verá o seguinte:</p>
<blockquote><p>TOP SECRET!</p></blockquote>
<p>Todos os restantes verão antes a mensagem:</p>
<blockquote><p>Este conteúdo está reservado a utilizadores autenticados.</p></blockquote>
<p>Por omissão, esta função verifica se o utilizador tem a autorização <code>read</code> (ou a <a href="http://codex.wordpress.org/Roles_and_Capabilities">capacidade</a> que for indicada no parâmetro <code>capability</code>). Se a autorização tiver sido concedida, é apresentado o conteúdo, caso contrário mostramos a mensagem de erro (ou a que for indicada no atributo <code>message</code>).</p>
<p>Dado que este novo <em>shortcode</em> permite parametrizar a capacidade requerida do utilizador e a mensagem de erro, temos alguma flexibilidade nas opções de validação e apresentação. Por exemplo:</p>
<blockquote>
<pre>[<!-- -->access capability="admin" error="Este conteúdo só pode ser visto por administradores."]TOP SECRET![/access]</pre>
</blockquote>
<h3 id="precaues">Precauções</h3>
<p>Apesar de poderosa, a API de <em>shortcodes</em> apresenta algumas limitações a ter em consideração.</p>
<p>Uma destas particularidades tem a ver com o facto de a função que interpreta os <em>shortcodes</em> varrer o conteúdo dos artigos e das páginas uma única vez. Isto significa que incluir <em>shortcodes</em> dentro uns dos outros pode não surtir os efeitos desejados. Por exemplo:</p>
<blockquote>
<pre>[<!-- -->access]
    O meu primeiro shortcode: [<!-- -->hello]
[/access]</pre>
</blockquote>
<p>Não funciona, apresentando aos utilizadores autenticados apenas o texto “O meu primeiro shortcode: [<!-- -->hello]”, sem substituir o fragmento “[<!-- -->hello]” como seria de esperar.</p>
<p>Uma forma de contornar esta limitação é passar o <code>$content</code> do <em>shortcode</em> pela função <a href="http://codex.wordpress.org/Function_Reference/do_shortcode"><code>do_shortcode()</code></a> antes de o devolver. Feita a alteração, a função terá o seguinte aspecto:</p>
<pre class="brush: php; title: ; notranslate">
function shortcode_access_control ( $atts, $content = null ) {
    extract( shortcode_atts( array(
        'capability' =&gt; 'read',
        'error' =&gt; 'Este conteúdo está reservado a utilizadores autenticados.',
    ), $atts ) );
    if (current_user_can( $capability ) &amp;&amp; !is_null( $content ))
        return do_shortcode( $content ); // Processamento de sub-shortcodes
    else
        return $error;
}

add_shortcode( 'access', 'shortcode_access_control' );
</pre>
<p>Aqui, a função <code>do_shortcode()</code> obriga o WordPress a interpretar recursivamente o conteúdo em busca de novos <em>shortcodes</em> para substituir.</p>
<p>Mais problemático é o facto do interpretador do WordPress não reconhecer duas ou mais ocorrências do mesmo <em>shortcode</em> encadeadas. Por exemplo:</p>
<blockquote>
<pre>[<!-- -->shortcode]
    [<!-- -->shortcode][/shortcode]
[/shortcode]</pre>
</blockquote>
<p>Não irá funcionar, mesmo usando a função <code>do_shortcode()</code>, dado que a função que interpreta os <em>shortcodes</em> privilegia a velocidade de processamento e não a correcta interpretação de estruturas complexas destes códigos.</p>
<p>Deve-se evitar usar hífens no nome do <em>shortcode</em>, pois estes não são correctamente reconhecidos pelo interpretador devido a um <em>bug</em> nas actuais versões do WordPress. Prefere-se aqui o uso do carácter _ (<em>underscore</em>). Também não são aceites parênteses rectos no valor de um atributo: algo como <code>[<!-- -->shortcode atributo="[<!-- -->valor]"]</code> irá falhar.</p>
<p>No próximo artigo, iremos explicar o processo de desenvolvimento de novas <em>widgets</em> para apresentação nos temas. Até lá, aguardamos questões e sugestões dos nossos leitores <a href="https://www.facebook.com/logOpenSourceConsulting">na nossa página no Facebook</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://log.pt/blog/2012/03/wordpress-tutorial-shortcodes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Desenvolvimento sobre WordPress (2) — Filtros</title>
		<link>http://log.pt/blog/2012/02/wordpress-tutorial-filters/</link>
		<comments>http://log.pt/blog/2012/02/wordpress-tutorial-filters/#comments</comments>
		<pubDate>Thu, 16 Feb 2012 17:16:33 +0000</pubDate>
		<dc:creator>Luís Rodrigues</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://log.pt/?p=11942</guid>
		<description><![CDATA[Na primeira parte desta série de artigos de introdução ao desenvolvimento sobre WordPress, aprendemos a personalizar um tema através dos hooks de acção. Este hooks permitem associar código nosso a acontecimentos de interesse no sistema, como o pedido de uma página ou a publicação de um artigo ou comentário. Tudo sem interferir com o núcleo [...]]]></description>
			<content:encoded><![CDATA[<p>Na <a href="http://log.pt/blog/2012/01/wordpress-tutorial-actions/">primeira parte</a> desta série de artigos de introdução ao desenvolvimento sobre WordPress, aprendemos a personalizar um tema através dos <em>hooks</em> de acção. Este <em>hooks</em> permitem associar código nosso a acontecimentos de interesse no sistema, como o pedido de uma página ou a publicação de um artigo ou comentário. Tudo sem interferir com o núcleo do WordPress, que se quer livre de código personalizado para facilitar as actualizações.</p>
<h3 id="filtros">Filtros</h3>
<p>Vimos também no primeiro artigo que existe uma segunda classe de <em>hooks</em>, chamados filtros, sobre os quais nos iremos agora debruçar. Estes são em tudo semelhantes às acções, com uma diferença de nota: todas as funções de filtro recebem pelo menos um parâmetro e retornam, transformado ou não, o primeiro desses parâmetros recebidos.</p>
<p>Por esse motivo, e como o próprio nome indica, são perfeitos para transformação e processamento de informação, ou para aplicar em validações da mesma, antes de a escrever na base de dados ou a mostrar ao visitante do site. Neste texto iremos experimentar alguns exemplos.</p>
<h3 id="omeuprimeirofiltro">O meu primeiro filtro</h3>
<p>Como antes, concentraremos as nossas modificações no ficheiro <em>functions.php</em> do tema, situado em <em>/wp-content/themes/<strong>pasta do tema</strong>/functions.php</em>, e só mais tarde aplicaremos o conhecimento adquirido ao desenvolvimento de uma nova extensão.</p>
<p>O procedimento para criação e registo de um filtro é semelhante ao das acções, sendo necessário escrever a função de filtragem em PHP e associá-la a um filtro do WordPress usando <a href="http://codex.wordpress.org/Function_Reference/add_filter"><code>add_filter()</code></a>.</p>
<p>Para o nosso primeiro exemplo, iremos personalizar a apresentação das nossas listagens, transformando o texto da hiperligação “Continuar a ler” dos artigos separados por um <em>More…</em> com algo um pouco mais elaborado.</p>
<p><div class="wp-caption aligncenter" style="width: 637px"><img id="ahiperligaoquepretendemosmodificar" src="http://log.pt/wp-content/uploads/2012/01/004-01-more-before.png" alt="A hiperligação que pretendemos modificar" width="627" height="446" /><p class="wp-caption-text">Figura 1: O que pretendemos modificar.</p></div></p>
<pre class="brush: php; title: ; notranslate">
function tutorial_the_content_more_link ( $output, $more_link_text ) {
    $more_link_url = get_permalink() . '#more-' . get_the_ID();
    $new_more_link_text = &quot;Continue a ler, modificado pelo meu primeiro filtro &amp;rarr;&quot;;
    $output = ' &lt;a href=&quot;' . $more_link_url . '&quot; class=&quot;more-link&quot;&gt;' . $new_more_link_text . '&lt;/a&gt;';
    return $output;
}
</pre>
<p>Tal como com as acções, é imperativo registar o filtro. Vamos usar a função <code>add_filter()</code> para associar a nossa função ao filtro <code>excerpt_more</code>:</p>
<pre class="brush: php; title: ; notranslate">
add_filter( 'the_content_more_link', 'tutorial_the_content_more_link', 10, 2 );
</pre>
<p>Por partes, então.</p>
<p>Primeiro que tudo, o filtro a que a vamos associar (<code>the_content_more_link</code>), recebe dois parâmetros: sendo o primeiro a hiperligação já construída, e o segundo o texto simples dessa hiperligação. O <code>2</code> na linha do <code>add_filter()</code> indica isso mesmo, à semelhança do que já acontecia com as acções. O <code>10</code> indica a prioridade do filtro, mais uma vez em tudo semelhante ao que vimos antes. Quanto maior, mais tarde na sequência de filtros do <code>the_content_more_link</code> há-de correr.</p>
<p>Neste caso, interessa-nos reconstruir por completo a hiperligação, não preservando o que vem de trás. Para tal, precisamos de construir o endereço de destino à custa das funções <a href="http://codex.wordpress.org/Function_Reference/get_permalink"><code>get_permalink()</code></a> e <a href="http://codex.wordpress.org/Function_Reference/get_the_ID"><code>get_the_ID()</code></a>, guardando-o na variável <code>$more_link_url</code>.</p>
<p>No final, redefinimos a variável <code>$output</code> com o HTML da hiperligação que pretendemos apresentar e retornamos esse valor. Se não for modificado por mais nenhum filtro, este será o HTML a apresentar ao visitante do <em>site</em>.</p>
<p><div class="wp-caption aligncenter" style="width: 646px"><img id="ahiperligaomodificadaportutorial_the_content_more_link" src="http://log.pt/wp-content/uploads/2012/01/004-02-more-after.png" alt="A hiperligação modificada por tutorial_the_content_more_link" width="636" height="430" /><p class="wp-caption-text">Figura 2: A hiperligação modificada.</p></div></p>
<p>É claro que a nossa função <code>tutorial_the_content_more_link()</code> pode conter código mais sofisticado para, por exemplo, apresentar o total de palavras no artigo.</p>
<pre class="brush: php; title: ; notranslate">
function tutorial_the_content_more_link_wordcount( $output, $more_link_text ) {
    global $post;
    $word_count = str_word_count( strip_tags( $post-&gt;post_content ) );
    $more_link_text = &quot;Continue a ler ($word_count palavras) &amp;rarr;&quot;;
    $more_link_url = get_permalink() . '#more-' . get_the_ID();
    $output = ' &lt;a href=&quot;' . $more_link_url . '&quot; class=&quot;more-link&quot;&gt;' . $more_link_text . '&lt;/a&gt;';
    return $output;
}

add_filter( 'the_content_more_link', 'tutorial_the_content_more_link_wordcount', 20, 2 );
</pre>
<p>Aqui, vamos precisar de obter dados do artigo em questão que não são passados por parâmetro à nossa função. Para isso declaramos a variável global <code>$post</code> na nossa função, de forma a podermos aceder ao valor de <code>$post-&gt;get_content</code>, que contém todo o texto do artigo.</p>
<p>Com o texto completo do artigo na nossa posse, podemos finalmente contabilizar o total de palavras com <a href="http://php.net/manual/en/function.str-word-count.php"><code>str_word_count</code></a>, tendo o cuidado primeiro de limpar o HTML existente no artigo usando <a href="http://php.net/manual/en/function.strip-tags.php"><code>strip_tags</code></a>. O resto é semelhante à primeira função que vimos, com a diferença de agora imprimirmos o total de palavras.</p>
<p><div class="wp-caption aligncenter" style="width: 619px"><img id="ahiperligaocomtotaldepalavrasnoartigo" src="http://log.pt/wp-content/uploads/2012/01/004-03-more-better.png" alt="A hiperligação com total de palavras no artigo" width="609" height="413" /><p class="wp-caption-text">Figura 3: A hiperligação com contador de palavras.</p></div></p>
<h3 id="encadeamentodefiltros">Encadeamento de filtros</h3>
<p>Em certos casos poderá ser necessário associar várias funções ao mesmo filtro. Não há qualquer problema: tal como as acções, os filtros são executados em sequência, segundo a prioridade definida (como nas acções, mais uma vez) e a ordem em que foram registados.</p>
<p>Para exemplificar este mecanismo, vamos alterar a apresentação do título do artigo com o filtro <code>the_title</code> para, mais uma vez, mostrar o contador de palavras, e também acrescentar uma <em>tag</em> HTML em torno do texto.</p>
<pre class="brush: php; title: ; notranslate">
function tutorial_the_title_em ( $title, $id ) {
    return &quot;&lt;em&gt;$title&lt;/em&gt;&quot;;
}

function tutorial_the_title_wordcount ( $title, $id ) {
    if ($id) {
        $post = &amp;get_post( $id );
        $word_count = str_word_count( strip_tags( $post-&gt;post_content ) );
        return $title . &quot; ($word_count palavras)&quot;;
    } else {
        return $title;
    }
}

add_filter( 'the_title', 'tutorial_the_title_em', 10, 2 );        // Prioridade 10
add_filter( 'the_title', 'tutorial_the_title_wordcount', 20, 2 ); // Prioridade 20
</pre>
<p>Dado que o filtro <code>the_title</code> aceita entre os seus parâmetros o identificador do artigo, e não havendo garantias de que a função vai correr dentro do <em>loop</em> de apresentação de posts do WordPress, teremos de obter o conteúdo do artigo sem recorrer à variável global <code>$post</code>. Usamos por isso a função <code>get_post()</code> do WordPress para conseguir o mesmo efeito.</p>
<p><div class="wp-caption aligncenter" style="width: 380px"><img id="ttulocomitlicoprimeiroetotaldepalavrasdepois" class=" " src="http://log.pt/wp-content/uploads/2012/01/004-04-title-one-two.png" alt="Título com itálico primeiro e total de palavras depois" width="370" height="79" /><p class="wp-caption-text">Figura 4: Título com itálico aplicado primeiro e total de palavras acrescentado depois.</p></div></p>
<p>Na sequência de filtros acima, o título é colocado em itálico primeiro e depois é-lhe acrescentado o total de palavras. Contudo, se invertermos a prioridade…</p>
<pre class="brush: php; title: ; notranslate">
add_filter( 'the_title', 'tutorial_the_title_em', 20, 2 );        // Prioridade 20
add_filter( 'the_title', 'tutorial_the_title_wordcount', 10, 2 ); // Prioridade 10
</pre>
<p>…então é aplicado o contador primeiro e depois é <em>tudo</em> posto a itálico.</p>
<p><div class="wp-caption aligncenter" style="width: 378px"><img id="ttulocomtotaldepalavrasprimeiroeitlicoaplicadodepois" class=" " src="http://log.pt/wp-content/uploads/2012/01/004-05-title-two-one.png" alt="Título com total de palavras primeiro e itálico aplicado depois" width="368" height="82" /><p class="wp-caption-text">Figura 5: Título com total de palavras acrescentado primeiro e itálico aplicado depois.</p></div></p>
<p><code>the_title</code> e <code>the_content_more_link</code> são apenas dois de uma imensa variedade de filtros. Existe no Codex uma <a href="http://codex.wordpress.org/Plugin_API/Filter_Reference">lista de todos os filtros suportados pelo WordPress</a>, sendo também possível criar novos filtros e, claro, usar os filtros criados por outros temas e <em>plugins</em>. Nunca é demais recomendar a <a href="http://adambrown.info/p/wp_hooks">WordPress Hook Database</a> de Adam Brown, contendo informação mais pormenorizada sobre todos os <em>hooks</em> suportados pelo WordPress em cada uma das suas versões.</p>
<h3 id="eliminarfiltros">Eliminar filtros</h3>
<p>Da mesma forma que associamos funções a filtros, também podemos eliminar essa associação. Vimos no primeiro artigo que esse processo era levado a cabo pela função <a href="http://codex.wordpress.org/Function_Reference/remove_action"><code>remove_action()</code></a>.</p>
<p>Aqui, passa-se exactamente o mesmo, a única diferença é a função chamar-se <a href="http://codex.wordpress.org/Function_Reference/remove_filter"><code>remove_filter()</code></a>. Por exemplo, a seguinte invocação impediria a execução da função <code>tutorial_the_title_wordcount()</code> previamente associada ao filtro <code>the_title</code>.</p>
<pre class="brush: php; title: ; notranslate">
// Retira o filtro com prioridade 10 apenas:
remove_filter( 'the_title', 'tutorial_the_title_wordcount', 10 );
// Retira o filtro com prioridade 20 apenas:
remove_filter( 'the_title', 'tutorial_the_title_wordcount', 20 );
</pre>
<p>Já a função <a href="http://codex.wordpress.org/Function_Reference/remove_all_filters"><code>remove_all_filters()</code></a> impede a execução de todas as funções associadas a um dado filtro. Por exemplo, todos os fitros <code>the_title</code> declarados antes desta linha deixarão de ser executados:</p>
<pre class="brush: php; title: ; notranslate">
remove_all_filters( 'the_title' );

// Mas este, associado depois da limpeza, já corre:
add_filter( 'the_title', 'tutorial_the_title_em', 10, 2 );
</pre>
<h3 id="novosfiltros">Novos filtros</h3>
<p>À semelhança do <a href="http://codex.wordpress.org/Function_Reference/do_action"><code>do_action()</code></a> apresentado na sessão anterior, que invoca uma acção (nova ou existente), existe uma função análoga para os filtros chamada <a href="http://codex.wordpress.org/Function_Reference/apply_filters"><code>apply_filters()</code></a>.</p>
<p>Podemos, por exemplo, aplicar os filtros de título do WordPress (incluindo os acima declarados) a uma cadeia arbitrária de caracteres fazendo:</p>
<pre class="brush: php; title: ; notranslate">
// Associar a função a um novo filtro:
add_filter( 'custom_the_title', 'tutorial_the_title_em', 10, 2 );

// Invocar o novo filtro...
$filtered_title = apply_filters( 'custom_the_title', 'Hello, world!', 0 )
echo $filtered_title;

// ...ou mesmo um filtro que já exista.
$filtered_title = apply_filters( 'the_title', 'Hello, world!', 0 )
echo $filtered_title;
</pre>
<h3 id="prximasesso"></h3>
<p>No próximo artigo, abordaremos a API de <em>shortcodes</em> do WordPress, um mecanismo com <em>tags</em> especiais que podem ser incluídas no conteúdo dos artigos com funcionalidade de apresentação difícil ou mesmo impossível de reproduzir através do editor visual.</p>
]]></content:encoded>
			<wfw:commentRss>http://log.pt/blog/2012/02/wordpress-tutorial-filters/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Terceiro Evento da Comunidade HTML5 PT</title>
		<link>http://log.pt/blog/2012/01/terceiro-evento-da-comunidade-html5-pt/</link>
		<comments>http://log.pt/blog/2012/01/terceiro-evento-da-comunidade-html5-pt/#comments</comments>
		<pubDate>Tue, 31 Jan 2012 10:25:26 +0000</pubDate>
		<dc:creator>Sérgio Santos</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[eventos]]></category>
		<category><![CDATA[HTML5]]></category>

		<guid isPermaLink="false">http://log.pt/?p=13172</guid>
		<description><![CDATA[O terceiro evento da comunidade Portuguesa de HTML5 realiza-se já no próximo dia 8 de Fevereiro, no Auditório da Microsoft Portugal às 18:30 horas. Para este evento foram escolhidas as talks: xRTML da Framework Realtime, por Sérgio Costa As novidades do CSS3, por Beatriz Olveira JScramble, por Rui Ribeiro O evento é gratuito e aberto [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://log.pt/blog/2012/01/terceiro-evento-da-comunidade-html5-pt/attachment/logo1/" rel="attachment wp-att-13182"><img class="alignright size-full wp-image-13182" src="http://log.pt/wp-content/uploads/2012/01/logo1.png" alt="" width="264" height="80" /></a>O terceiro evento da comunidade Portuguesa de HTML5 realiza-se já no próximo dia 8 de Fevereiro, no Auditório da Microsoft Portugal às 18:30 horas.</p>
<p>Para este evento foram escolhidas as talks:</p>
<ul>
<li>xRTML da Framework Realtime, por Sérgio Costa</li>
<li>As novidades do CSS3, por Beatriz Olveira</li>
<li>JScramble, por Rui Ribeiro</li>
</ul>
<p>O evento é gratuito e aberto a todos, mas os lugares são limitados.</p>
<p>Mais informações aqui: <a title="Terceiro Eventos da Comunidade HTML5 PT" href="http://lanyrd.com/2012/html5pt/" target="_blank">http://lanyrd.com/2012/html5pt/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://log.pt/blog/2012/01/terceiro-evento-da-comunidade-html5-pt/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dicas de tipografia para a web</title>
		<link>http://log.pt/blog/2012/01/dicas-de-tipografia-para-a-web/</link>
		<comments>http://log.pt/blog/2012/01/dicas-de-tipografia-para-a-web/#comments</comments>
		<pubDate>Fri, 27 Jan 2012 12:59:20 +0000</pubDate>
		<dc:creator>Filipe Serrazina</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[fontes]]></category>
		<category><![CDATA[tipografia]]></category>
		<category><![CDATA[ux]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://log.pt/?p=12452</guid>
		<description><![CDATA[Um dos elementos mais ignorados para um Webdesign de excelência tem sido a arte da tipografia. Uma grande parte desta falta de atenção deriva do ainda relativo pouco suporte que existe nos browsers. Escolher o tipo de fonte apropriado para complementar o design tornou-se uma tarefa bastante difícil com a variedade de tipos de fonte [...]]]></description>
			<content:encoded><![CDATA[<p><a title="in Taipei by no_typographic_man, on Flickr" href="http://www.flickr.com/photos/kusamakura/429346289/"><img src="http://farm1.staticflickr.com/178/429346289_f0d559ccc3_z.jpg" alt="in Taipei" width="640" height="428" /></a></p>
<p>Um dos elementos mais ignorados para um Webdesign de excelência tem sido a arte da tipografia. Uma grande parte desta falta de atenção deriva do ainda relativo pouco suporte que existe nos browsers.</p>
<p>Escolher o tipo de fonte apropriado para complementar o design tornou-se uma tarefa bastante difícil com a variedade de tipos de fonte que os browsers suportam actualmente.</p>
<p>Até há pouco tempo, utilizar fontes que não estavam por norma instaladas nos computadores, implicava recorrer a imagens, Flash, ou a qualquer outro truque. Mas com a implementação nos browsers mais recentes da propriedade <em>@font-face</em>, permitiu aos designers uma maior criatividade na composição dos seus designs.</p>
<h3>Consequências na escolha da fonte</h3>
<p>Algumas das fontes das quais ganhámos acesso nunca foram feitas para ser utilizada num ecrã, quer seja por serem esteticamente inadequadas ou porque simplesmente são inelegíveis.</p>
<p>Também existem problemas técnicos relativos à renderização das fontes. Existem diversas inconsistências entre os browsers. O tamanho dos ficheiros das fontes, pode fazer com que as páginas passem a pesar para cima da centena de Kb.</p>
<p><a href="http://en.wikipedia.org/wiki/Robert_Bringhurst">Robert Bringhurst</a>, um conhecido tipógrafo disse que:</p>
<blockquote><p>A tipografia existe para honrar o conteúdo</p></blockquote>
<h3>Legibilidade</h3>
<p>O aspecto mais importante a ter em conta quando escolhemos um tipo de fonte é a sua legibilidade.</p>
<p>Muitos designers não gostam muito da ideia de usar unicamente as fontes que são usadas por defeito pelos browsers &#8211; algo que é compreensível &#8211; mas que tem uma razão de ser, é que essas fontes tornam o conteúdo de fácil leitura.</p>
<p>Quando se escolhe uma fonte para a nossa página, devemos optar por uma que seja simples. Devemos manter o aspecto simples e não enveredar por um tipo de fonte muito complexa.</p>
<p>Devemos ainda deixar a parte criativa para outros elementos como os cabeçalhos, mas devemos manter o conteúdo o mais simples e legível possível. Uma fonte com um peso médio que tem serifas simples ou idealmente sem serifas é a melhor escolha.</p>
<p><div id="attachment_13142" class="wp-caption aligncenter" style="width: 610px"><img class="size-large wp-image-13142" title="serif-sanserif" src="http://log.pt/wp-content/uploads/2012/01/serif-sanserif2-600x396.jpg" alt="" width="600" height="396" /><p class="wp-caption-text">Diferenças entre fontes serif e sans serif</p></div></p>
<p>O contraste deve ser elevado, e nunca devemos utilizar fontes abaixo dos 13px. Também não é boa ideia reduzir o espaçamento entre linhas, pelo contrário, muitas vezes é aconselhável aumentar este espaço.</p>
<p>Um último aspecto importante para manter a legibilidade, é, não ter mais do que três tipos de fontes na mesma página.</p>
<h3>Escolher as melhores Fontes</h3>
<p>Escolher a fonte para utilizar num site é uma das chaves para o sucesso do design que muitas vezes é menosprezada.
Ao escolhermos a família de fontes a utilizar devemos assegurar que estas são legíveis nos diferentes tamanhos utilizados no design do site.</p>
<p><div class="wp-caption alignnone" style="width: 610px"><a title="Typeface by angermann, on Flickr" href="http://www.flickr.com/photos/angermann/164830768/"><img src="http://farm1.staticflickr.com/46/164830768_81618e2c89.jpg" alt="Typeface" width="600" height="450" /></a><p class="wp-caption-text">A escolha do tipo de fonte deve ir de encontro ao objetivo do site</p></div></p>
<p>Não vale a pena termos bom conteúdo no site se depois este não é legível. Também é importante escolher um tipo de fonte que vá de encontro ao &#8220;espírito&#8221; do site. Por exemplo uma fonte de estilo <em>Gothic</em> não seria a mais apropriada para um site infantil, mas talvez servisse para um site de um espetáculo Draconiano.</p>
<h3>Definir o Contraste</h3>
<p>O contraste é também ele um aspecto importante quando trabalhamos com tipografia.</p>
<p><div class="wp-caption alignnone" style="width: 610px"><a title="Contrast by elizabethdonoghue, on Flickr" href="http://www.flickr.com/photos/elizabeth_donoghue/2993134068/"><img src="http://farm4.staticflickr.com/3140/2993134068_d9d4a0d6f7.jpg" alt="Contrast" width="600" height="450" /></a><p class="wp-caption-text">O contraste entre o texto e o fundo ajuda na leitura do conteúdo</p></div></p>
<p>Um texto a vermelho pálido sobre um fundo verde pálido, pode funcionar bem, por exemplo estampado numa t-shirt, mas nunca será muito legível.</p>
<p>O texto existe para ser lido e compreendido, o contraste deve ser suficiente para assegurar que o texto é legível.
Se não tivermos certeza de que o contraste é suficiente, podemos fazer um screenshot da página, abrir num editor de imagem e transformar a imagem em tons de cinza. Conseguimos ter a percepção se o contraste é suficiente.</p>
<h3>Escolher o Tamanho</h3>
<p>Quando surgiu o conceito da Web 2.0 notou-se o surgimento de uma estranha tendência, a utilização de fontes de reduzida dimensão passou a ser moda. Alguns designers diziam que se adaptava ao estilo minimalista do design adoptado. Como a maioria dos utilizadores não possui uma visão raio-x, ou uma acuidade 10/10, o tamanho reduzido das fontes não serve o propósito de legibilidade.</p>
<p><div class="wp-caption alignnone" style="width: 610px"><a title="Font size 200! by Grey cells, on Flickr" href="http://www.flickr.com/photos/hmmmmm/4711643242/"><img src="http://farm5.staticflickr.com/4022/4711643242_8428bea8d3.jpg" alt="Font size 200!" width="600" height="450" /></a><p class="wp-caption-text">O tamanho do texto é muito importante para a legibilidade</p></div></p>
<p>Não devemos definir o texto abaixo dos 13px, devemos pelo contrário, optar por tamanhos superiores. Por exemplo o tamanho da fonte no site da <em>I Love Typography</em> está definido para 16px.</p>
<p>No entanto temos também de ter em conta que uma fonte demasiado grande força os utilizadores a fazerem demasiado scroll para conseguirem ler todo o conteúdo. Encontrar o equílibrio é normalmente possível escolhendo uma fonte de tamanho médio, outra opção, talvez mais correcta é fazer com que o tamanho da fonte se ajuste às preferências de cada utilizador.</p>
<h3>Hierarquia</h3>
<p>Variar o tamanho da fonte é a melhor forma de diferenciar o conteúdo. A utilização constante e consistente de diferentes tamanhos de fontes ao longo da página reforçam a importância de cada elemento para os utilizadores.</p>
<p><div class="wp-caption alignnone" style="width: 610px"><a title="Moai, Ahu Tongariki, Easter Island by maryatexitzero, on Flickr" href="http://www.flickr.com/photos/marypmadigan/4174704590/"><img src="http://farm5.staticflickr.com/4037/4174704590_20654bcc1d.jpg" alt="Moai, Ahu Tongariki, Easter Island" width="600" height="400" /></a><p class="wp-caption-text">Uma boa hierarquia ajuda na identificação dos blocos de texto</p></div></p>
<p>Também serve para os utilizadores poderem fazer uma leitura de varrimento e captar as principais ideias que pretendemos comunicar — o que poderá servir para captar a atenção e levá-los a permanecer mais tempo no nosso site.</p>
<p>Cada elemento na página deve guiar progressivamente o utilizador pelo conteúdo que o site pretendo transmitir. A forma como a página é apresentada pode reforçar a hierarquia através da utilização de diferentes tamanhos, negritos, sublinhados, etc.
A mistura entre fontes com e sem serifas também pode servir para criar um efeito harmonioso.</p>
<p>Usar uma escala para definir os diferentes tamanhos pode conseguir uma boa hierarquização. Por exemplo, a escala pode ser de 14px para o corpo de texto, e ir aumentando de tamanho, 16, 18, 21, 24, 36, 48, 60 até 72 px para os maiores cabeçalhos.</p>
<p>Podemos utilizar os nossos próprios padrões, tendo sempre em atenção a consistência entre as páginas.</p>
<h3>Espaço Branco</h3>
<p>O espaço branco é o espaço negativo que existe entre os diferentes blocos que compõem uma página, não necessariamente branco, mas os “espaços” que permitem que o conteúdo respire.
Devemos deixar o texto respirar. O espaço branco deve ser algo sempre presente nas páginas. Este espaço ajuda a que a nossa atenção se focalize no conteúdo, e se é o texto que deve falar mais alto, então devemos &#8220;ouvi-lo&#8221;. Devemos deixar espaço branco nas margens, nos cabeçalhos e nos rodapés.</p>
<p>Podemos usar propriedades das CSS para conseguir este espaço, como o line-height, este deve ser pelo menos 140% do tamanho do texto.</p>
<p>Os tipógrafos costumam passar horas a trabalhar no &#8220;micro espaço&#8221; que existe entre cada caracter. Passam muito tempo a tentar encontrar a melhor harmonia entre o negro do caracter e o espaço branco que o rodeia. Cabe aos web designers, pensar no espaço macro, nos &#8220;buracos&#8221; que existem entre os blocos de texto das páginas.</p>
<h3>Alinhamento</h3>
<p>Uma grelha bem planeada é sempre uma boa base para um design sólido. As páginas devem ser divididas num sistema de colunas, linhas, cabeçalhos, barras laterais e rodapés, de modo a conduzir o olhar do utilizador para o conteúdo mais importante.</p>
<p><div id="attachment_13002" class="wp-caption aligncenter" style="width: 610px"><img class="size-full wp-image-13002" title="text-alignment" src="http://log.pt/wp-content/uploads/2012/01/text-alignment.jpg" alt="" width="600" height="400" /><p class="wp-caption-text">Deve-se usar sempre o texto alinhado à esquerda</p></div></p>
<p>Na web não é boa ideia usar um alinhamento justificado. Vai separar as palavras de uma maneira pouco natural, dificultando a leitura.
No exemplo utilizado podemos ver que na primeira linha as palavras estão muito mais &#8220;arrumadas&#8221; que nas linhas 2 e 3, em que a separação das palavras é enorme.</p>
<h3>Limitar o número de fontes</h3>
<p>Não devem ser usadas mais do que três tipos de fontes no design de uma página, e preferencialmente devemos usar apenas duas. Com duas fontes é possível criar muitas variações que servem o nosso propósito. Se forem necessárias três fontes, esta última deve ser usada com decoro de forma a que não acrescente confusão ao design.</p>
<h3>Outras dicas úteis para uma melhor tipografia</h3>
<ol>
<li><strong>Não utilizar aspas verticais.
</strong>As aspas verticais (também conhecidas como ambidestras), foram concebidas para reduzir o número de teclas num teclado, basta apenas uma tecla para abrir e fechar as citação.
Para contornarmos esta limitação, devemos usar as aspas normais, para isso devemos colocar do lado esquerdo da citação: <strong>&amp;ldquo;</strong>, e do lado direito <strong>&amp;rdquo;</strong>, o browser irá reproduzir assim: “O meu pequeno pónei”.</li>
<li><strong>Utilizar um traço em vez de dois hífens.
</strong>Dois hífens consecutivos (&#8211;) parece algo descuidado e na realidade interrompe o fluxo natural da mensagem. O leitor, fica preso no meio dos dois hífens a tentando perceber o significado.
Para contornar este atentado ao sistema cognitivo do leitor, devemos usar, um traço N ou um traço M.O primeiro tem o comprimento de um N maiúsculo e deve ser usado para:- Intervalos de valores (1–10)- Relações e conexões (Benfica ganha ao Sporting, 3–0)- Adjetivos compostos (MS–DOS)</p>
<p>Escrevemos um traço N (En Dash) no html com: <strong>&amp;ndash;</strong></p>
<p>Um traço M tem o comprimento de um M maiúsculo e é usado para indicar uma mudança temporária no raciocínio, quer no meio quer no final de uma frase. Escrevemos um traço M (Em Dash) no html com: <strong>&amp;mdash;</strong></li>
<li><strong>Ajustar o espaçamento das letras, palavras, e espaço entre linhas nos cabeçalhos.
</strong>Podemos, com recurso às CSS, ajustar o espaçamento dos cabeçalhos. Por defeito existe muito espaço branco entre cada letra, palavra e linha se o tamanho da letra for maior que 16.
Quanto maior for o tamanho da fonte, mais parece que as letras se separam umas das outras.
Devemos ajustar esta fragmentação com letras mais estreitas, palavras mais juntas e um espaçamento de linha mais reduzido.</li>
<li><strong>Usar a unidade EM para redimensionar o texto.
</strong>Dimensionar o texto na Web não é uma tarefa fácil. Na web os utilizadores tem a hipótese de redimensionar o texto de forma a que se adapte melhor às suas necessidades.Se estamos a usar pixeis (px) estamos a usar uma medida que é estática, e desta forma a retirar a oportunidade para os utilizadores redimensionarem o texto.Se usarmos EM, que é uma medida relativa, o site irá adaptar-se à medida que o utilizador usar o zoom para aumentar ou diminuir o texto.</li>
<li><strong>Adicionar espaço extra entre as linhas.
</strong>Um espaço entre linhas generoso irá tornar a leitura mais fácil. Como medida padrão para um bom espaçamento é definir a altura de cada linha para 150% do tamanho do texto. Exemplo: line-height: 1.5em</li>
<li><strong>Usar as reticências corretamente em vez de três pontos
</strong>Quando terminamos uma frase com reticências, normalmente usamos três pontos para indicar uma interrupção. Devido ao comprimento do ponto final, três pontos, não parecem uma interrupção. O símbolo correcto a usar é uma elipse. Para usar uma elipse usamos <strong>&amp;hellip;</strong> que fica assim: …</li>
</ol>
<h3>Fontes</h3>
<ul>
<li>I Love Typography (<a href="http://ilovetypography.com/">http://ilovetypography.com/</a>)</li>
<li>8 Faces (<a href="http://8faces.com/">http://8faces.com/</a>)</li>
</ul>
<h3>Artigos</h3>
<ul>
<li>On Web Typography (<a href="http://www.alistapart.com/articles/on-web-typography/">http://www.alistapart.com/articles/on-web-typography/</a>)</li>
<li>Typography Guidelines And References (<a href="http://www.smashingmagazine.com/typography-guidelines-and-references/">http://www.smashingmagazine.com/typography-guidelines-and-references/</a>)</li>
<li>“What Font Should I Use?%rdquo;: Five Principles for Choosing and Using Typefaces (<a href="http://www.smashingmagazine.com/2010/12/14/what-font-should-i-use-five-principles-for-choosing-and-using-typefaces/">http://www.smashingmagazine.com/2010/12/14/what-font-should-i-use-five-principles-for-choosing-and-using-typefaces/</a>)</li>
</ul>
<h3>Tutoriais</h3>
<ul>
<li>CSS Typography: The Basics (<a href="http://sixrevisions.com/css/css-typography-01/">http://sixrevisions.com/css/css-typography-01/</a>)</li>
<li>10 Web Typography Rules Every Designer Should Know (<a href="http://www.webdesignerdepot.com/2009/02/10-web-typography-rules-every-designer-should-know-2/">http://www.webdesignerdepot.com/2009/02/10-web-typography-rules-every-designer-should-know-2/</a>)</li>
<li>22 Advanced CSS Text Effects And Web Typography Tips (<a href="http://www.1stwebdesigner.com/css/advanced-css-text-effects-web-typography-tips/">http://www.1stwebdesigner.com/css/advanced-css-text-effects-web-typography-tips/</a>)</li>
<li>10 Best Web Typography Tutorials (<a href="http://idesignow.com/css/10-best-web-typography-tutorials.html">http://idesignow.com/css/10-best-web-typography-tutorials.html</a>)</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://log.pt/blog/2012/01/dicas-de-tipografia-para-a-web/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Desenvolvimento sobre WordPress (1) — Acções</title>
		<link>http://log.pt/blog/2012/01/wordpress-tutorial-actions/</link>
		<comments>http://log.pt/blog/2012/01/wordpress-tutorial-actions/#comments</comments>
		<pubDate>Mon, 02 Jan 2012 14:45:55 +0000</pubDate>
		<dc:creator>Luís Rodrigues</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://log.pt/?p=11572</guid>
		<description><![CDATA[Este é o primeiro de uma série de artigos de introdução ao desenvolvimento para WordPress que iremos publicar ao longo de 2012, não exigindo mais dos leitores interessados do que um WordPress previamente instalado em servidor próprio e conhecimentos rudimentares de PHP. Pretendemos com isto disseminar know-how sobre a plataforma, bem como partilhar algumas das [...]]]></description>
			<content:encoded><![CDATA[<p>Este é o primeiro de uma série de artigos de introdução ao desenvolvimento para WordPress que iremos publicar ao longo de 2012, não exigindo mais dos leitores interessados do que um WordPress previamente instalado em servidor próprio e conhecimentos rudimentares de PHP. Pretendemos com isto disseminar <em>know-how</em> sobre a plataforma, bem como partilhar algumas das lições que fomos aprendendo ao longo dos anos.</p>
<p><div id="attachment_11542" class="wp-caption alignright" style="width: 178px"><img class="size-medium wp-image-11542  " src="http://log.pt/wp-content/uploads/2011/12/003-01-wp-functions-php-168x300.png" alt="Localização do functions.php no tema Twenty Eleven" width="168" height="300" /><p class="wp-caption-text">Figura 1: Localização do functions.php no tema Twenty Eleven.</p></div></p>
<p>Num artigo futuro abordaremos o desenvolvimento de <em>plugins</em>, mas por agora vamos limitar-nos a criar funcionalidade usando o ficheiro <em>functions.php</em>, mais conveniente para as nossas pequenas experiências. Este ficheiro, que existe na raíz de cada tema WordPress, em <em>/wp-content/themes/<strong>(pasta do tema)</strong>/functions.php</em> (figura 1), permite a execução de código auxiliar que não faz sentido aplicar transversalmente num <em>plugin</em>.</p>
<p>Importa salientar que o <em>functions.php</em> é específico ao seu tema, e por isso só corre quando o tema está activo, deixando de ter efeito quando se escolhe um diferente.</p>
<p>Vamos, pois, abrir o <em>functions.php</em> no nosso editor de código predilecto (à falta de melhor, um editor de texto básico como o Notepad serve perfeitamente), e prepararmo-nos para dar os primeiros passos por entre as engrenagens do WordPress.</p>
<h3><em>Hooks</em></h3>
<p>A interface de desenvolvimento (ou API) do WordPress assenta maioritariamente no conceito de <em>“hooks”</em>, ou ganchos. Estes <em>hooks</em> dizem respeito a uma série de eventos que podem ocorrer no ciclo de vida da plataforma, e nos quais podemos “pendurar” as nossas próprias funções, alterando o comportamento do WordPress em resposta aos mesmos.</p>
<p>A maior vantagem deste mecanismo de <em>hooks</em> é permitir modificar a plataforma sem mexer no código fonte do próprio WordPress, nem nos temas e <em>plugins</em> de terceiros. As alterações introduzidas através de <em>hooks</em> são modulares e aglomeráveis com as de outros <em>plugins</em> ou temas.</p>
<p>Existem <em>hooks</em> de dois tipos: acções e filtros.</p>
<p>As acções são comportamentos despoletados por uma situação específica, tal como a apresentação do cabeçalho ou rodapé das páginas, a publicação de um artigo, ou a criação de uma nova taxonomia.</p>
<p>Os filtros são semelhantes, com a diferença de terem a capacidade de receber dados, transformá-los, e passá-los à frente. Destes falaremos no próximo artigo.</p>
<h3>A minha primeira acção</h3>
<p>Para construirmos a nossa primeira acção, precisaremos de criar uma função que a implemente. No final do ficheiro <em>functions.php</em> vamos teclar o seguinte código que escreve uma <em>tag</em> HTML:</p>
<pre class="brush: php; title: ; notranslate">
function tutorial_meta_greeting () {
    echo '&lt;meta name=&quot;greeting&quot; content=&quot;Olá, mundo!&quot;&gt;';
}
</pre>
<p>A função <code>tutorial_meta_greeting</code>, só por si, ainda não faz nada. É preciso associá-la a um <em>hook</em> do WordPress que a possa invocar, acrescentando a seguinte linha:</p>
<pre class="brush: php; title: ; notranslate">
add_action( 'wp_head', 'tutorial_meta_greeting', 10, 0 );
</pre>
<p>Esta linha diz ao WordPress para executar a nossa função sempre que ocorra um evento com a etiqueta <code>wp_head</code>, um <em>hook</em> que é despoletado aquando da geração do cabeçalho de uma página. Estamos, assim, a escrever uma <em>tag</em> <code>&lt;meta&gt;</code> nos cabeçalhos das nossas páginas. O resultado é visível consultando o HTML de qualquer página do <em>site</em>:</p>
<p><div class="wp-caption aligncenter" style="width: 386px"><img src="http://log.pt/wp-content/uploads/2011/12/003-02-action-greeting.png" alt="Resultado de tutorial_meta_greeting" width="376" height="59" /><p class="wp-caption-text">Figura 2: O resultado da nossa primeira experiência.</p></div></p>
<p>Podemos associar as funções que quisermos ao mesmo <em>hook</em>. Por vezes, no entanto, é preciso garantir que certas funções têm precedência sobre outras. Aqui entra o terceiro parâmetro da função <a href="http://codex.wordpress.org/Function_Reference/add_action"><code>add_action</code></a>, que diz respeito à prioridade de execução. O parâmetro é opcional, mas no nosso exemplo explicitámos ser 10. Outra função associada a <code>wp_head</code> mas com um nível de prioridade mais baixo correria <em>antes</em> da nossa função. Com um valor mais alto, correria <em>depois</em>. Por exemplo:</p>
<pre class="brush: php; title: ; notranslate">
function tutorial_meta_before () {
    echo '&lt;meta name=&quot;before&quot; content=&quot;Antes da saudação.&quot;&gt;';
}

function tutorial_meta_after () {
    echo '&lt;meta name=&quot;after&quot; content=&quot;Depois da saudação.&quot;&gt;';
}

add_action( 'wp_head', 'tutorial_meta_before', 5, 0 );
add_action( 'wp_head', 'tutorial_meta_after', 20, 0 );
</pre>
<p>O quarto parâmetro, que é opcional, indica o número de argumentos que o <em>hook</em> passa à função. No caso do <code>wp_head</code>, não são passados parâmetros.</p>
<p><code>wp_head</code> é apenas uma de muitas acções. Existe no Codex uma <a href="http://codex.wordpress.org/Plugin_API/Action_Reference">lista de todas as acções suportadas pelo WordPress</a>, sendo também possível criar novas acções e, claro, responder a outras oferecidas por temas e <em>plugins</em>. Também muito útil é o serviço <a href="http://adambrown.info/p/wp_hooks">WordPress Hook Database</a> de Adam Brown, que contém uma referência mais técnica de todos os <em>hooks</em> suportados pelo WordPress em cada uma das suas versões.</p>
<h3>Mais e melhor</h3>
<p>As acções podem servir-se de muitos dados da plataforma, não estando limitadas ao que recebem como argumento. Por exemplo, podemos alterar a nossa função <code>tutorial_meta_greeting</code> para apresentar uma mensagem mais amigável:</p>
<pre class="brush: php; title: ; notranslate">
function tutorial_meta_greeting ()
{
    global $current_user;
    if (is_user_logged_in()) {
        echo '&lt;meta name=&quot;greeting&quot; content=&quot;Olá, ' . $current_user-&gt;display_name . '!&quot;&gt;';
    } else {
        echo '&lt;meta name=&quot;greeting&quot; content=&quot;Olá, mundo!&quot;&gt;';
    }
}
</pre>
<p>A função acima verifica que o visitante está autenticado usando a função <a href="http://codex.wordpress.org/Function_Reference/is_user_logged_in"><code>is_user_logged_in</code></a> do WordPress, e tendo obtido a variável global <code>$current_user</code>, que contém os dados do utilizador, apresenta uma saudação personalizada. Os restantes receberão uma mensagem mais genérica na <em>tag</em> <code>&lt;meta&gt;</code>.</p>
<p><div class="wp-caption aligncenter" style="width: 416px"><img class=" " src="http://log.pt/wp-content/uploads/2011/12/003-03-action-greeting-personalized-png.png" alt="Resultado de tutorial_meta_greeting" width="406" height="189" /><p class="wp-caption-text">Figura 3: Saudação personalizada.</p></div></p>
<p>Inserir uma simples <em>tag</em> <code>&lt;meta&gt;</code> no cabeçalho pode não parecer das coisas mais úteis, mas é um exercício simples para explicar a essência do funcionamento dos <em>hooks</em> do WordPress.</p>
<p>Podemos aplicar este conhecimento num exercício mais prático, como adicionar o bloco HTML do Google Analytics ao rodapé das nossas páginas:</p>
<pre class="brush: php; title: ; notranslate">
function tutorial_add_google_analytics () {
    $tracking_code = 'UA-XXXXX-X'; // Não se esqueça de me definir
    echo '&lt;script src=&quot;http://www.google-analytics.com/ga.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;';
    echo '&lt;script type=&quot;text/javascript&quot;&gt;';
    echo 'var pageTracker = _gat._getTracker(&quot;' . $tracking_code . '&quot;);';
    echo 'pageTracker._trackPageview();';
    echo '&lt;/script&gt;';
}
add_action( 'wp_footer', 'tutorial_add_google_analytics' );
</pre>
<p>Outras utilizações práticas das acções contemplam, por exemplo:</p>
<ul>
<li>Envio de <em>emails</em> sempre que um novo artigo é publicado;</li>
<li>Registo das autenticações feitas pelos utilizadores num ficheiro de <em>log</em> ou em base de dados;</li>
<li>Inicializar ou preparar dados no início de um pedido de página.</li>
</ul>
<h3>Remover acções</h3>
<p>Tal como associamos funções a <em>hooks</em>, também temos a possíbilidade de as retirar com a função <a href="http://codex.wordpress.org/Function_Reference/remove_action"><code>remove_action</code></a>. Suponhamos que apenas nos interessam estatísticas de utilização de visitantes autenticados, e que por isso devemos ignorar a função <code>tutorial_add_google_analytics</code> para os restantes.</p>
<pre class="brush: php; title: ; notranslate">
if (!is_user_logged_in())
    remove_action( 'wp_footer', 'tutorial_add_google_analytics' );
</pre>
<p>Mais uma vez, usámos <code>is_user_logged_in</code> para determinar se o visitante está autenticado, e se não estiver retiramos a função <code>tutorial_add_google_analytics</code> do rol de acções a executar no <em>hook</em> <code>wp_footer</code>. À semelhança do <code>add_action</code>, podemos indicar a prioridade e o número de argumentos se quisermos apenas retirar ocorrências específicas de uma função.</p>
<p>Uma aplicação simples e muito prática de <code>remove_action</code> consiste em eliminar algumas das <em>tags</em> HTML que denunciam versões antigas e potencialmente inseguras a visitantes mal-intencionados. Como esta:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;meta name=&quot;generator&quot; content=&quot;WordPress 3.3&quot;&gt;
</pre>
<p>Para ocultar estes dados, inseridos no cabeçalho pela função interna do WordPress <code>wp_generator</code>, é preciso acrescentar o seguinte ao <em>functions.php</em>:</p>
<pre class="brush: php; title: ; notranslate">
remove_action( 'wp_head', 'wp_generator' );
</pre>
<h3>Novas acções</h3>
<p>Definir novas acções personalizadas é tão simples quando invocá-las em qualquer parte do nosso código usando <a href="http://codex.wordpress.org/Function_Reference/do_action"><code>do_action</code></a>. Acrescentando ao final do <em>functions.php</em> o seguinte:</p>
<pre class="brush: php; title: ; notranslate">
do_action( 'tutorial_new_action' );                             // Sem argumentos
do_action( 'tutorial_new_action', $arg1 );                      // Com 1 argumento
do_action( 'tutorial_new_action', $arg1, $arg2 );               // Com 2 argumentos
do_action( 'tutorial_new_action', $arg1, $arg2, ..., $argN );   // Com N argumentos
</pre>
<p>Esta linha irá activar todas as funções que estejam associadas ao <em>hook</em> <code>tutorial_new_action</code>, podendo passar-lhes zero ou mais argumentos.</p>
<p>No próximo artigo, irei debruçar-me sobre a segunda classe de <em>hooks</em>, os filtros, onde aprenderemos a criar funções para transformar a apresentação de conteúdos do WordPress.</p>
<p>Até lá teremos muito gosto em receber <em>feedback</em> e ouvir as questões dos leitores <a href="https://www.facebook.com/logOpenSourceConsulting">na nossa página no Facebook</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://log.pt/blog/2012/01/wordpress-tutorial-actions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Parallax Scrolling Design</title>
		<link>http://log.pt/blog/2011/12/parallax-scrolling-design/</link>
		<comments>http://log.pt/blog/2011/12/parallax-scrolling-design/#comments</comments>
		<pubDate>Tue, 13 Dec 2011 19:30:12 +0000</pubDate>
		<dc:creator>Filipe Serrazina</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://log.pt/?p=11032</guid>
		<description><![CDATA[Parallax segundo a enciclopédia britânica é definido como o deslocamento aparente ou a aparente diferença de direção de um objeto visto de dois pontos diferentes, que não estejam em linha reta com o objeto. O efeito Parallax ou parallax scrolling no web design é uma técnica que envolve várias camadas (layers) de elementos (imagens de [...]]]></description>
			<content:encoded><![CDATA[<p><em>Parallax</em> segundo a <a href="http://www.merriam-webster.com/dictionary/parallax">enciclopédia britânica</a> é definido como o deslocamento aparente ou a aparente diferença de direção de um objeto visto de dois pontos diferentes, que não estejam em linha reta com o objeto.</p>
<p>O efeito <em>Parallax</em> ou <em>parallax scrolling</em> no web design é uma técnica que envolve várias camadas (<em>layers</em>) de elementos (imagens de fundo, caixas de texto, etc.) com velocidades e perspetivas diferentes, criando uma ilusão de 3D.</p>
<p>Atualmente com o recurso a um interface bem definido, a bibliotecas de JavaScript (jQuery) e às CSS3, podemos criar sites que pareçam mais reais e criativos, sem ter que recorrer ao Flash ou ao Video.</p>
<h3>Usabilidade</h3>
<p>Quando surgiram os primeiros sites a recorrer a esta técnica, muitos designers apressaram-se a adotá-la para os seus próprios sites, muitas vezes sem um planeamento adequado.</p>
<p>É sempre bom experimentar novas técnicas, mas quando começamos a planear os projectos à volta de uma técnica, corremos o risco de o projeto não servir os propósitos iniciais.</p>
<p>Utilizar uma técnica apenas porque é novidade, não é uma boa prática e pode levar a que um projeto acarrete inúmeros problemas de usabilidade.</p>
<p>Se acedermos a alguns sites que utilizam esta técnica, ficamos com a sensação que alguns funcionariam melhor se os elementos que a compõem permanecessem imóveis.</p>
<h3>Considerações a ter em conta ao usar <em>Parallax</em></h3>
<p>Ao desenharmos um site que recorra ao efeito <em>parallax</em> devemos ter em conta alguns dos seguintes fatores:</p>
<ul>
<li><strong>Carregar previamente todos os elementos gráficos: </strong>se o design contêm muitos elementos gráficos devemos, antes de disponibilizar informação ao utilizador, carregar todos os elementos gráficos. Com isto iremos proporcionar uma experiência de utilização mais agradável.</li>
<li><strong>Dispositivos móveis:</strong> devemos ter uma atenção redobrada com o dispositivos móveis, pois os utilizadores poderão não ter a mesma experiência de utilização como têm nos <em>browsers</em> dos computadores.</li>
<li><strong>Tamanhos dos ecrãs: </strong>testar o design em diferentes ecrãs, com diferentes resoluções e garantir que em todos temos a mesma experiência de utilização.</li>
</ul>
<h3>Potenciais problemas inerentes à utilização</h3>
<p>Os sites que fazem uso desta técnica, como o site da <a href="http://www.nikebetterworld.com/">Nike Better World</a>, numa primeira impressão aparentam funcionar perfeitamente, mas algumas questões se levantam.</p>
<p>O primeiro problema é o facto de esta técnica ainda ser bastante recente, e por isso mesmo ser encarada como novidade. Se recuarmos um pouco no tempo, até aos anos 90, proliferou o uso massivo de .gifs animados, que também na altura eram novidade. Era impressionante ver num site não só todo o conteúdo estático mas também por exemplo um gato que dançava!!</p>
<p><img class="aligncenter" src="http://img42.imageshack.us/img42/561/218catplayingelectricgu.gif" alt="rocker kitten animated gifs" /></p>
<p>Como nos recordamos, a novidade dos .gifs animados, passou rapidamente da experiência de vermos alguma animação nas páginas para algo que criava ruído e distraía os utilizadores.</p>
<p>Outro problema relacionado com esta técnica é a ainda falta de suporte nos browsers dos tablets. Ainda é difícil recriar toda a experiência de utilização nestes dispositivos.</p>
<p>Com o cada vez maior número de dispositivos móveis, e enquanto o suporte não melhora, temos de pensar se vale a pena criar um site que utiliza esta técnica apenas para os browsers que correm nos computadores pessoais.</p>
<h3>Usar ou não usar <em>Parallax</em></h3>
<p>Depende sempre do objetivo do projeto.</p>
<p>Para percebermos se devemos ou não adoptar esta técnica num dos nossos projetos precisamos de saber quais os objetivos que pretendemos atingir. Se o conceito que o <em>parallax</em> oferece é o ponto central do projeto e dos seus objetivos então podemos utilizar &#8211; se não, o mais provável é estarmos a usar esta técnica apenas por ser novidade, e provavelmente o projecto irá deparar-se com maiores problemas de usabilidade.</p>
<h3>Exemplos</h3>
<p>Os exemplos que se seguem contêm sites que utilizam o efeito do <em>parallax</em> da melhor forma, a começar pelo exemplo mais popular Nike Better World. Como podemos reparar a maioria dos sites inspira-se neste exemplo.</p>
<h4><a href="http://www.nikebetterworld.com/">Nike Better WOrld</a></h4>
<p><img class="aligncenter" title="Nike Better World" src="http://webdesignerwall.com/wp-content/uploads/2011/11/nike-better-world.jpg" alt="" width="560" height="350" /></p>
<h4><a href="http://www.smartusa.com/">Smart USA</a></h4>
<p><img class="aligncenter" title="Smart USA" src="http://webdesignerwall.com/wp-content/uploads/2011/11/smart-usa.jpg" alt="" width="560" height="350" /></p>
<h4><a href="http://www.nintendo.com.au/gamesites/mariokartwii/">Mario Kart Wii</a></h4>
<p><img class="aligncenter" title="Mario Kart" src="http://webdesignerwall.com/wp-content/uploads/2011/11/mario-kart.jpg" alt="" width="560" height="350" /></p>
<h4><a href="http://www.beetle.com/">Beetle</a></h4>
<p><img class="aligncenter" title="Bettle" src="http://www.tangledindesign.com/blog/wp-content/uploads/2011/09/22.jpg" alt="" width="500" height="300" /></p>
<h4><a href="http://activatedrinks.com/">Activate Drinks</a></h4>
<p><img class="alignnone" title="Activate Drinks" src="http://webdesignerwall.com/wp-content/uploads/2011/11/active-drinks.jpg" alt="" width="560" height="350" /></p>
<h3>Tutoriais</h3>
<ul>
<li><a href="http://www.ianlunn.co.uk/blog/code-tutorials/recreate-nikebetterworld-parallax/">Recreate NikeBetterWorld Parallax</a></li>
<li><a href="http://coding.smashingmagazine.com/2011/07/12/behind-the-scenes-of-nike-better-world/">Behind the Scenes of NikeBetterWorld</a></li>
<li><a href="http://jonraasch.com/blog/scrolling-parallax-jquery-plugin">Parallax Scrolling jQuery Plugin</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://log.pt/blog/2011/12/parallax-scrolling-design/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Melhorar o desempenho do MySQL sem aborrecer DBAs</title>
		<link>http://log.pt/blog/2011/11/melhorar-o-desempenho-do-mysql-sem-aborrecer-dbas/</link>
		<comments>http://log.pt/blog/2011/11/melhorar-o-desempenho-do-mysql-sem-aborrecer-dbas/#comments</comments>
		<pubDate>Mon, 28 Nov 2011 16:55:55 +0000</pubDate>
		<dc:creator>Luís Rodrigues</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://log.pt/?p=10562</guid>
		<description><![CDATA[No acto de desenhar e desenvolver sobre uma base de dados MySQL, é bem possível que surjam problemas de desempenho, principalmente quando é preciso tratar quantidades exorbitantes de dados. Alguns destes problemas podem ser colmatados com uma arquitectura eficiente, uma correcta definição dos índices das tabelas ou, em último caso, escalando o hardware. No entanto, [...]]]></description>
			<content:encoded><![CDATA[<p>No acto de desenhar e desenvolver sobre uma base de dados MySQL, é bem possível que surjam problemas de desempenho, principalmente quando é preciso tratar quantidades exorbitantes de dados. Alguns destes problemas podem ser colmatados com uma arquitectura eficiente, uma correcta definição dos índices das tabelas ou, em último caso, escalando o <em>hardware</em>.</p>
<p>No entanto, nem sempre é praticável investir num <em>upgrade</em> das máquinas, ou alterar o motor de armazenamento, a estrutura da base de dados ou sequer a política de indexação das tabelas. Seguem-se algumas técnicas de optimização de expressões SQL que programadores podem adoptar unilateralmente no sentido de melhorar o desempenho das suas consultas. Tudo sem ser preciso aborrecer os administradores da base de dados.</p>
<h3>O MySQL explica</h3>
<p>O primeiro passo de qualquer optimização de expressões SQL, uma vez <a title="Program optimization: When to optimize" href="http://en.wikipedia.org/wiki/Program_optimization#When_to_optimize">determinada a sua necessidade</a>, é compreender o funcionamento interno dos pedidos que fazemos à base de dados.</p>
<p>O <em>statement</em> <a href="http://dev.mysql.com/doc/refman/5.6/en/explain.html"><code>EXPLAIN</code></a> deve ser a arma de eleição para este combate. Até ao MySQL 5.6.3, servia &#8220;apenas&#8221; para avaliar expressões do tipo <code>SELECT</code>, mas nas versões mais recentes pode ser aplicado a todas as operações, sejam de leitura, inserção, actualização ou eliminação. Para fazer uso desta funcionalidade basta prefaciar qualquer instrução SQL com a palavra <code>EXPLAIN</code>.</p>
<p>A principal utilidade do <code>EXPLAIN</code> está em revelar o mecanismo de indexação usado para obter os resultados de um pedido. A indexação das colunas de uma tabela permite pesquisas mais rápidas, da mesma forma que o índice de capítulos de um livro ou a arrumação alfabética de uma lista telefónica ou enciclopédia nos facilita a consulta e leitura. A troco de algum espaço em disco e velocidade de escrita, o sistema gestor da base de dados que use índices pode encontrar o que procura directamente em vez de o fazer percorrendo as tabelas registo a registo.</p>
<p><a title="EXPLAIN Output Format" href="http://dev.mysql.com/doc/refman/5.6/en/explain-output.html">Olhando para o resultado de uma chamada ao <code>EXPLAIN</code></a>, em especial para as colunas <code>possible_keys</code> (contendo os candidatos a índice a utilizar) e <code>key</code> (o índice realmente usado), obtemos informação crucial para identificar se uma tabela precisa que determinada coluna esteja indexada ou se, pelo contrário, a coluna tem índices que não se usam porque as expressões de consulta se encontram indevidamente construídas. Este artigo irá debruçar-se sobre algumas destas, e oferecer alternativas práticas.</p>
<p>Outras indicações do <code>EXPLAIN</code> a ter em conta são as colunas <code>Extra</code> (onde qualquer referência a índices é perfeita) e <code>type</code> (onde a palavra <em>index</em> significa <em>full index scan</em>, o que é péssimo para o desempenho).</p>
<h3>Contra relógio</h3>
<p>A função <a href="http://dev.mysql.com/doc/refman/5.6/en/information-functions.html#function_benchmark"><code>BENCHMARK()</code></a>, que permite executar uma expressão SQL repetidas vezes e retornar o tempo de resposta, é outra ferramenta relativamente útil, principalmente quando é preciso testar expressões aritméticas ou com parâmetros constantes.</p>
<p>Embora possa ser usada para avaliar expressões do tipo <code>SELECT</code>, importa realçar que a execução de um pedido <code>SELECT BENCHMARK(N, SELECT ...)</code> irá resultar na reutilização de estruturas de memória e outros mecanismos de optimização automática do MySQL, pelo que os tempos reportados irão certamente parecer mais optimistas do que na realidade. A função <code>BENCHMARK()</code> também nos diz pouco sobre o tempo consumido pelo servidor, sendo por vezes necessário calcular a média de múltiplos <em>benchmarks</em> para nos aproximarmos de um valor real.</p>
<h3>O que não vale a pena fazer</h3>
<p>Felizmente, o optimizador interno do MySQL tem inteligência para melhorar, de forma transparente, determinadas expressões. De entre as melhorias automáticas que o MySQL faz contam-se:</p>
<ul>
<li>Eliminação de parênteses desnecessários;</li>
<li>Substituição de variáveis por constantes que lhes estejam atribuídas;</li>
<li>Junção das condições em <code>WHERE</code> e <code>HAVING</code> quando não existem funções de agregação ou <code>GROUP BY</code>;</li>
<li>Ordenação ideal das tabelas num <code>INNER JOIN</code>.</li>
</ul>
<p>Atacar estas situações no código pode melhorar a legibilidade do mesmo, mas não terá efeitos práticos sobre o desempenho das pesquisas.</p>
<h3>A união faz a força</h3>
<p>A junção de condições com o operador <code>OR</code>, no MySQL e noutros sistemas de bases de dados, é puro veneno.</p>
<p>Isto porque, quando confrontado com um <code>OR</code>, o sistema de base de dados ignora a indexação de muitas das colunas, uma vez que esta deixa de ser limitativa para os resultados a apresentar. Embora alguns sistemas consigam optimizar sequências de condições <code>OR</code> mais simples, é má ideia confiar numa optimização automática que não está garantida.</p>
<p>A boa notícia é que há uma solução para contornar este problema. A má notícia é que a solução é <em>feia</em>.</p>
<p>Adoptemos o seguinte exemplo, muito simples, que pesquisa a tabela de artigos de um blogue e retorna todos os registos cujo título comece por A ou tenha um artigo-pai cujo título comece por A:</p>
<pre class="brush: sql; title: ; notranslate">
SELECT p.ID
    FROM wp_posts p, wp_posts pai
    WHERE p.post_title LIKE 'A%'
        OR (p.post_parent = pai.ID AND pai.post_title LIKE 'A%')
</pre>
<p>Esta expressão pode ser reescrita à custa de múltiplos <code>SELECT</code>s cujos resultados são depois agregados usando a palavra-chave <code>UNION</code> (ou <code>UNION ALL</code>, que é ainda mais eficiente, mas só no caso de não ser preciso limpar registos duplicados).</p>
<pre class="brush: sql; title: ; notranslate">
SELECT p.ID
    FROM wp_posts p
    WHERE p.post_title LIKE 'A%'
UNION
SELECT p.ID
    FROM wp_posts p, wp_posts pai
    WHERE p.post_parent = pai.ID AND pai.post_title LIKE 'A%'
</pre>
<p>Embora a vantagem de reescrever a expressão desta forma não pareça nada intuitiva, o que acontece é que várias pesquisas feitas recorrendo a índices são consideravelmente mais rápidas do que uma única pesquisa feita sem essa ajuda. Esta diferença torna-se bastante perceptível com o aumento do tamanho da tabela a consultar, podendo a optimização traduzir-se numa redução do tempo de pesquisa de várias horas para poucos minutos.</p>
<p>Aplicando o <code>EXPLAIN</code> às duas expressões da consulta, torna-se evidente, olhando para o campo <code>key</code>, qual delas não está a usar os índices que tem à disposição.</p>
<pre class="brush: sql; highlight: [6]; title: ; notranslate">
&gt; EXPLAIN SELECT p.ID, p.post_title FROM wp_posts p, wp_posts pai WHERE (p.post_parent = pai.ID AND pai.post_title LIKE 'A%') OR p.post_title LIKE 'A%';
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | p     | ALL  | post_parent   | NULL | NULL    | NULL | 2412 |             |
|  1 | SIMPLE      | pai   | ALL  | PRIMARY       | NULL | NULL    | NULL | 2412 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
2 rows in set (0.00 sec)
</pre>
<p>Se, contudo, pedirmos ao MySQL para &#8220;explicar&#8221; a expressão com <code>UNION</code>, detectamos que a chave <code>PRIMARY</code> é usada para relacionar o pai de um artigo através do seu identificador, o que não acontecia antes, e por conseguinte reduzindo o número de linhas (em <code>rows</code>) que é preciso considerar.</p>
<pre class="brush: sql; highlight: [6]; title: ; notranslate">
&gt; EXPLAIN SELECT p.ID, p.post_title FROM wp_posts p, wp_posts pai WHERE p.post_parent = pp.ID AND pai.post_title LIKE 'A%' UNION SELECT p.ID, p.post_title FROM wp_posts p WHERE p.post_title LIKE 'A%';
+----+--------------+------------+--------+---------------+---------+---------+--------------------+------+-------------+
| id | select_type  | table      | type   | possible_keys | key     | key_len | ref                | rows | Extra       |
+----+--------------+------------+--------+---------------+---------+---------+--------------------+------+-------------+
|  1 | PRIMARY      | p          | ALL    | post_parent   | NULL    | NULL    | NULL               | 2412 |             |
|  1 | PRIMARY      | pai        | eq_ref | PRIMARY       | PRIMARY | 8       | blog.p.post_parent |    1 | Using where |
|  2 | UNION        | p          | ALL    | NULL          | NULL    | NULL    | NULL               | 2412 | Using where |
|NULL| UNION RESULT | &lt;union1,2&gt; | ALL    | NULL          | NULL    | NULL    | NULL               | NULL |             |
+----+--------------+------------+--------+---------------+---------+---------+--------------------+------+-------------+
4 rows in set (0.00 sec)
</pre>
<p>Felizmente para quem tem de ler e entender o código, a utilização do <code>UNION</code> nem sempre é necessária. Quando basta escolher de entre um leque de valores constantes para uma coluna, como no exemplo abaixo, estes podem ser refeitos usando a comparação <code>IN</code>.</p>
<pre class="brush: sql; title: ; notranslate">
SELECT p.ID
FROM wp_posts p
WHERE p.ID = 1
    OR p.ID = 2
    OR p.ID = 3
    OR p.ID = 5
    OR p.ID = 8
    OR p.ID = 13
</pre>
<p>Isto pode ser transformado em:</p>
<pre class="brush: sql; title: ; notranslate">
SELECT p.ID
FROM wp_posts p
WHERE p.ID IN (1, 2, 3, 5, 8, 13)
</pre>
<p>A comparação <code>IN</code> verifica a presença de uma variável numa lista de valores e é extremamente eficiente quando a lista é pequena e composta apenas por constantes. (É importante reforçar esta condição porque muito embora <code>IN (constante1, constante2, ...)</code> seja eficiente, <code>IN (SELECT ...)</code> já não é.)</p>
<h3>Encadeamento de consultas</h3>
<p>Outro deslize comum em que a facilidade de escrita e leitura choca com a optimização das consultas é no caso dos <code>SELECT</code>s encadeados, que ocorrem quando o programador está a pensar em termos procedimentais e não nos dados e nas suas relações. Por exemplo:</p>
<pre class="brush: sql; title: ; notranslate">
SELECT
    c.id,
    c.nome,
    (SELECT SUM(horas)
        FROM relatorio
        WHERE colaborador_id = c.id) AS total_horas
FROM colaboradores c
</pre>
<p>Esta expressão não é a ideal porque o segundo <code>SELECT</code> (dentro do <code>SELECT</code> principal) obriga a um esforço suplementar do sistema da base de dados, que é pago em tempo de resposta e ocupação de memória. Embora haja situações em que o uso de pedidos encadeados é inevitável, neste caso a expressão pode ser facilmente refeita através de um <code>INNER JOIN</code> muito mais eficiente.</p>
<pre class="brush: sql; title: ; notranslate">
SELECT
    c.id,
    c.nome,
    SUM(h.horas) AS total_horas
FROM colaboradores c
INNER JOIN horas h
    ON h.colaborador_id = c.id
</pre>
<h3>Funções e os pedidos que funcionam mal</h3>
<p>Outra atenção a tomar reside na aplicação de funções a comparações com campos indexados. Estas situações atrapalham a <em>cache</em> de pedidos e reduzem (tal como acima) o desempenho da base de dados. Deve-se pesar a necessidade de ter estas funções na consulta <em>versus</em> a possibilidade de passar parâmetros condicionais pré-processados ou de obter um conjunto de dados maior e aplicar posteriormente uma rotina de filtragem.</p>
<h3>Dois em um</h3>
<p>Programadores que desconhecem as palavras mágicas <code>ON DUPLICATE KEY UPDATE</code> tendem a incorrer noutro erro comum: o de fazer um <code>SELECT</code> para verificar a existência de determinado registo, seguido por uma instrução de <code>INSERT</code> para o criar caso não exista ou então <code>UPDATE</code> caso esteja presente.</p>
<p>Não só a estrutura de decisão envolvida neste processo complica desnecessariamente o código, como obriga a duas ligações à base de dados: uma para o <code>SELECT</code> inicial, e outra para o pedido de inserção ou actualização. A solução mais prática é fazer um único <code>INSERT ... ON DUPLICATE KEY UPDATE</code>, matando estes dois coelhos com uma cajadada só.</p>
<h3>Mas há mais!</h3>
<p>Embora este artigo esteja centrado no desenvolvimento sobre MySQL, os cuidados e recomendações são aplicáveis a muitos outros sistemas de gestão de bases de dados, como Oracle ou Microsoft SQL Server, bastando adaptar a sintaxe SQL.</p>
<p>As possíveis optimizações ao SQL das consultas também não se esgotam aqui, pelo que não termino o artigo sem recomendar um conjunto de recursos <em>online</em> úteis para quem pretenda alargar os seus horizontes neste capítulo do desenvolvimento sobre bases de dados.</p>
<ul>
<li><a href="http://dev.mysql.com/doc/refman/5.6/en/statement-optimization.html">Optimizing SQL Statements</a></li>
<li><a href="http://www.mysql.com/why-mysql/performance/index.html">MySQL Performance Tuning and Optimization Resources</a></li>
<li><a href="http://www.mysqlperformanceblog.com/">MySQL Performance Blog</a>, de Peter Zaitsev</li>
<li><a href="http://www.bigdbahead.com/">Big DBA Head</a>, de Matthew Yonkovit</li>
<li><a href="http://net.tutsplus.com/tutorials/other/top-20-mysql-best-practices/">Top 20+ MySQL Best Practices</a>, por Burak Guzel</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://log.pt/blog/2011/11/melhorar-o-desempenho-do-mysql-sem-aborrecer-dbas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>9 dicas sobre Responsive Web Design</title>
		<link>http://log.pt/blog/2011/11/9-dicas-sobre-responsive-web-design/</link>
		<comments>http://log.pt/blog/2011/11/9-dicas-sobre-responsive-web-design/#comments</comments>
		<pubDate>Thu, 10 Nov 2011 12:35:41 +0000</pubDate>
		<dc:creator>Filipe Serrazina</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[responsive]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://log.pt/?p=8782</guid>
		<description><![CDATA[Existe um novo conceito entre os web designers intitulado Responsive Design. A primeira pessoa que fez menção a este termo foi Ethan Marcotte num artigo intitulado Responsive Design que escreveu para o blog A List Apart. No artigo o Ethan descreve o processo de como utilizar layouts dinâmicos juntamente com as media queries para redimencionar [...]]]></description>
			<content:encoded><![CDATA[<p><div class="wp-caption aligncenter" style="width: 610px"><a href="http://www.colly.com"><img title="colly.com" src="http://cdn.designmodo.com/wp-content/uploads/2011/10/1.jpg" alt="#" width="600" height="340" /></a><p class="wp-caption-text">Responsive Design utilizado em diferentes dispositivos</p></div></p>
<p>Existe um novo conceito entre os web designers intitulado <strong>Responsive Design</strong>. A primeira pessoa que fez menção a este termo foi Ethan Marcotte num artigo intitulado <a href="http://www.alistapart.com/articles/responsive-web-design/">Responsive Design</a> que escreveu para o blog A List Apart.</p>
<p>No artigo o Ethan descreve o processo de como utilizar layouts dinâmicos juntamente com as <em>media queries</em> para redimencionar os layouts dos sites de forma a que estes se ajustem a qualquer tamanho de ecrã.</p>
<p>Mas afinal o que é o Responsive Design? Como refere <a href="http://thinkvitamin.com/design/beginners-guide-to-responsive-web-design/">Nick Pettit</a>, a questão não é tanto o que é, mas sim os problemas que este pode resolver. Como sabemos os computadores já não são os únicos dispositivos que podem aceder à Web. Os smartphones e tablets evoluiram e com isso o panorama da Web para dispositivos móveis.</p>
<p>As pessoas esperam poder aceder à Web nos seus smartphones tão facilmente como o fazem nos seus computadores. Em resposta a esta necessidade começou-se a criar versões móveis dos sites.
Cada site passou a ter a versão &#8220;normal&#8221; e uma bónus, a versão &#8220;móvel&#8221;.</p>
<p>O espectro de tamanhos de ecrã e resoluções está a aumentar a cada dia, e criar uma versão diferente do site para cada dispositivo é praticamente impossível. Este é um problema que o Responsive Design vem tentar resolver.</p>
<p>O termo Responsive Design, é a forma de, utilizando grelhas fluídas, layouts fluídos e as <em><a href="http://reference.sitepoint.com/css/mediaqueries" target="_blank">@media queries</a></em> conseguir adaptar o site ao manancial de dispositivos com diferentes tamanhos de ecrã que existem hoje.</p>
<p>Desta forma um utilizador que esteja a ver o site num smartphone, num tablet, ou num pc de secretária, verá o site adaptar-se automaticamente ao tamanho do ecrã de cada um dos dispositivos.</p>
<p>Com o advento dos dispositivos móveis, o Responsive Design torna-se ainda mais apelativo, como refere Luke Wroblewski num artigo intitulado <a href="http://www.lukew.com/presos/preso.asp?26">Designing for Mobile First</a>.</p>
<p>Nesse artigo o Luke aconselha-nos a começar a desenhar o site no ecrã mais pequeno. Desta forma asseguramos que teremos um excelente site para dispositivos móveis, o que força os designers a focar-se no que realmente interessa aos utilizadores.</p>
<p>Qual a melhor forma de construir um site que seja &#8220;Responsive&#8221;? Depende sempre do site em questão, mas existe uma série de normas que começam a emergir como boas práticas.</p>
<p>Aqui ficam 9 dicas para implementar Responsive Web Design:</p>
<ol>
<li><strong>Utilizar as <em>@media queries</em></strong><span class="Apple-style-span" style="font-weight: normal;"> para redimensionar o layout para qualquer tamanho de ecrã, tendo sempre em atenção que só isto não o transforma num site responsive.</span></li>
<li><strong>Utilizar layouts fluídos</strong><span class="Apple-style-span" style="font-weight: normal;"> que consigam adaptar-se a qualquer tamanho de ecrã. Não devemos desenhar um layout para os iPhone/Android, outro para os tablets e outro para os computadores. Devemos sempre mantê-lo fluído, para o caso de aparecer um novo dispositivo com um tamanho de ecrã diferente.</span></li>
<li><strong>Criar as grelhas do site</strong><span class="Apple-style-span" style="font-weight: normal;"> baseadas no conteúdo do site.</span><strong> </strong><span class="Apple-style-span" style="font-weight: normal;">As grelhas que existem raramente servem o propósito do site, uma vez que elas são feitas para diferentes tipos de conteúdo e raramente se encaixam no tipo de conteúdo que o site vai ter. Os layouts devem ser criados a partir do conteúdo.</span></li>
<li><strong>Começar com o tamanho mais pequeno</strong><span class="Apple-style-span" style="font-weight: normal;">. Devemos começar com o tamanho de ecrã mais pequeno, utilizando as </span><em style="font-weight: normal;"><em>@media queries</em></em><span class="Apple-style-span" style="font-weight: normal;"> para ajustar os elementos. Começar com uma coluna, para os smartphones e ir aumentando o tamanho do layout para ecrãs maiores, em vez de fazermos ao contrário.</span></li>
<li><strong>Utilizar as bibliotecas de JavaScript para as Media Queries</strong><span class="Apple-style-span" style="font-weight: normal;"> de forma a dar suporte aos browsers mais antigos que de outra forma não sabem o que fazer. Ao começarmos do tamanho mais pequeno para o maior os browsers dos computadores necessitam de lidar com as @media queries, precisamos de garantir que os browsers mais antigos funcionam, utilizando estas bibliotecas de Javascript.</span></li>
<li><strong>Não utilizar o Photoshop/Fireworks.</strong><span class="Apple-style-span" style="font-weight: normal;"> Devemos desenhar os nossos componentes no browser. É praticamente impossível desenhar um layout fluído no Photoshop. Começar no browser desde o primeiro instante é uma muito boa prática.</span></li>
<li><strong>Redimensionar as imagens</strong><span class="Apple-style-span" style="font-weight: normal;"> utilizando a propriedade img { max-width: 100%; }. Para imagens muito grandes devemos considerar utilizar um plugin de Javascript como o </span><a style="font-weight: normal;" href="https://github.com/scottjehl/Responsive-Images">Responsive Images</a><span class="Apple-style-span" style="font-weight: normal;"> que permite fazer apenas o download das imagens para o dispositivo que estejamos a utilizar. Se estivermos num smartphone só faz o download das imagens utilizadas para esse layout permitindo desta forma poupar no tráfego de dados.</span></li>
<li><strong>Carregar o conteúdo essencial primeiro</strong><span class="Apple-style-span" style="font-weight: normal;">. Pode haver elementos no site, que sirvam como conteúdo auxiliar. Devemos carregar esses elementos depois do conteúdo principal recorrendo ao </span><a style="font-weight: normal;" href="http://adactio.com/journal/4497/">JavaScript</a><span class="Apple-style-span" style="font-weight: normal;">.</span></li>
<li><strong>Não se preocupar com a perfeição</strong><span class="Apple-style-span" style="font-weight: normal;">. Haverá sempre utilizadores que não vão conseguir aceder ao site da melhor forma, seja por terem browsers demasiado antigos, ou por terem o JavaScript desativado. Esses utilizadores são cada vez mais raros. Se eles virem o layout para smartphones no computador, não é o fim do mundo. O site continua a ser perfeitamente usável.</span></li>
</ol>
<div>
<p>Temos de ter sempre em mente que o Responsive Design ainda é um conceito novo com novas ideias e novas ferramentas que estão sempre a ser atualizadas e substituídas por outras melhores.</p>
<h3>Links úteis:</h3>
<ul>
<li>Responsive Web Design (<a href="http://www.alistapart.com/articles/responsive-web-design/">http://www.alistapart.com/articles/responsive-web-design/</a>)</li>
<li>Beginner`s Guide to Responsive Web Design (<a href="http://thinkvitamin.com/design/beginners-guide-to-responsive-web-design/">http://thinkvitamin.com/design/beginners-guide-to-responsive-web-design/</a>)</li>
<li>Responsive Web Design: 50 Examples and Best Practices (<a href="http://designmodo.com/responsive-design-examples/">http://designmodo.com/responsive-design-examples/</a>)</li>
<li>10 Excellent Tools for Responsive Web Design (<a href="http://sixrevisions.com/tools/responsive-web-design/">http://sixrevisions.com/tools/responsive-web-design/</a>)</li>
<li>10 Tips For Designing Mobile Websites (<a href="http://labs.thesedays.com/blog/2010/07/16/10-tips-for-designing-mobile-websites/">http://labs.thesedays.com/blog/2010/07/16/10-tips-for-designing-mobile-websites/</a>)</li>
<li>8 Tools and Scripts for Responsive Web Design (<a href="http://webdesignledger.com/tools/8-tools-and-scripts-for-responsive-web-design">http://webdesignledger.com/tools/8-tools-and-scripts-for-responsive-web-design</a>)</li>
</ul>
</div>
]]></content:encoded>
			<wfw:commentRss>http://log.pt/blog/2011/11/9-dicas-sobre-responsive-web-design/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SAPO Codebits 2011</title>
		<link>http://log.pt/blog/2011/11/sapo-codebits-2011/</link>
		<comments>http://log.pt/blog/2011/11/sapo-codebits-2011/#comments</comments>
		<pubDate>Tue, 08 Nov 2011 13:49:47 +0000</pubDate>
		<dc:creator>Sérgio Santos</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[eventos]]></category>

		<guid isPermaLink="false">http://log.pt/?p=10222</guid>
		<description><![CDATA[&#8220;3 dias. 24 horas por dia. 800 participantes.&#8221; A V edição do SAPO Codebits decorre nos próximos dias 10, 11 e 12 de Novembro, no Pavilhão Atlântico em Lisboa, e junta programadores, geeks, criativos e entusiastas de tecnologia. Para além das conferências com oradores nacionais e internacionais, existem também workshops, concursos de programação, quizzes, karaoke, [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignright size-full wp-image-10232" src="http://log.pt/wp-content/uploads/2011/11/codebits.png" alt="" width="200" height="150" /></p>
<blockquote><p>&#8220;3 dias. 24 horas por dia. 800 participantes.&#8221;</p></blockquote>
<p>A V edição do SAPO Codebits decorre nos próximos dias 10, 11 e 12 de Novembro, no Pavilhão Atlântico em Lisboa, e junta programadores, geeks, criativos e entusiastas de tecnologia.</p>
<p>Para além das conferências com oradores nacionais e internacionais, existem também workshops, concursos de programação, quizzes, karaoke, jogos de vídeo, LEGO, comida e bebida.</p>
<p>Uma experiência inesquecível a que log não poderia faltar!</p>
<p>Mais informações aqui: <a href="http://codebits.eu" target="_blank">http://codebits.eu</a></p>
]]></content:encoded>
			<wfw:commentRss>http://log.pt/blog/2011/11/sapo-codebits-2011/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Silicon Valley comes to Lisbon</title>
		<link>http://log.pt/blog/2011/11/silicon-valley-comes-to-lisbon/</link>
		<comments>http://log.pt/blog/2011/11/silicon-valley-comes-to-lisbon/#comments</comments>
		<pubDate>Mon, 07 Nov 2011 23:58:12 +0000</pubDate>
		<dc:creator>Sérgio Santos</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[eventos]]></category>

		<guid isPermaLink="false">http://log.pt/?p=10082</guid>
		<description><![CDATA[Integrado na Semana Global do Empreendedorismo, o Silicon Valley comes to Lisbon &#8220;é um evento sobre empreendedorismo, inovação, mentes abertas, troca de ideias e networking inspirado no Silicon Valley comes to Oxford, que se realiza anualmente nesta cidade inglesa&#8221;. Este evento irá decorrer em Lisboa, nos próximos dias 17 e 18 de Novembro, e contará [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://log.pt/blog/2011/11/silicon-valley-comes-to-lisbon/attachment/svc2lx/" rel="attachment wp-att-10112"><img class="alignright size-full wp-image-10112" src="http://log.pt/wp-content/uploads/2011/11/svc2lx.png" alt="" width="196" height="270" /></a>Integrado na Semana Global do Empreendedorismo, o Silicon Valley comes to Lisbon &#8220;é um evento sobre empreendedorismo, inovação, mentes abertas, troca de ideias e networking inspirado no Silicon Valley comes to Oxford, que se realiza anualmente nesta cidade inglesa&#8221;.</p>
<p>Este evento irá decorrer em Lisboa, nos próximos dias 17 e 18 de Novembro, e contará com a presença de oradores como Paul Kedrosky da Kauffman Foundation, Patrick Vlaskovits da Lean Startup, Tony Fernandes da UE Group User Experience, Raymond Nasr ex-Google, Philip Rosedale criador do Second Life, Daniel Kraft da Stanford/Singularity, Peter Cohan do Babson College, Sean Ammirati da ReadWriteWeb, Bill Burnett da d.school Stanford, André Ribeirinho fundador do Adegga.com, entre outros.</p>
<p>Mais informações aqui: <a href="http://www.svc2lx.com/" target="_blank">http://www.svc2lx.com/</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://log.pt/blog/2011/11/silicon-valley-comes-to-lisbon/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Page Caching using disk: basic

Served from: log.pt @ 2012-05-18 01:01:40 -->
