<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2enclosuresfull.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Tutorial City</title>
	
	<link>http://tutorial-city.net</link>
	<description>Tutoriais em desenvolvimento web</description>
	<lastBuildDate>Tue, 07 Sep 2010 14:31:26 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1-alpha</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/tutorial-city/XDvR" /><feedburner:info uri="tutorial-city/xdvr" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><media:category scheme="http://www.itunes.com/dtds/podcast-1.0.dtd">Arts/Design</media:category><itunes:explicit>no</itunes:explicit><itunes:subtitle>Tutoriais em desenvolvimento web</itunes:subtitle><itunes:category text="Arts"><itunes:category text="Design" /></itunes:category><feedburner:emailServiceId>tutorial-city/XDvR</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item>
		<title>Redesign do Tutorial City</title>
		<link>http://feedproxy.google.com/~r/tutorial-city/XDvR/~3/mgEL68pnWBI/</link>
		<comments>http://tutorial-city.net/noticias/redesign-do-tutorial-city/#comments</comments>
		<pubDate>Tue, 07 Sep 2010 14:30:05 +0000</pubDate>
		<dc:creator>Tutorial City</dc:creator>
				<category><![CDATA[Notícias]]></category>
		<category><![CDATA[redesign]]></category>

		<guid isPermaLink="false">http://tutorial-city.net/?p=825</guid>
		<description><![CDATA[O Tutorial City voltou, e de cara novíssima! Depois de alguns meses sem atividade e algumas semanas em manutenção, este blog volta com muito mais força e tutoriais mais elaborados. O que vai mudar? Durante todo o tempo de existência &#8230; <a href="http://tutorial-city.net/noticias/redesign-do-tutorial-city/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>O Tutorial City voltou, e de cara novíssima! Depois de alguns meses sem atividade e algumas semanas em manutenção, este blog volta com muito mais força e tutoriais mais elaborados.<span id="more-825"></span></p>
<h2>O que vai mudar?</h2>
<p>Durante todo o tempo de existência desse blog foi complicado, pra mim, criar os vídeo tutoriais, então a primeira atitude mais forte é uma diminuição considerável de tutoriais em vídeo. Mas há males que vem para o bem, tutoriais em vídeo não podem ser tão elaborados quanto tutoriais escritos, porque vídeos muito longos tendem a ser cansativos, e separar em várias partes não é necessariamente uma boa ideia, já que não é muito legal ficar alternando entre vários vídeos pra ver só aquela parte que você queria tirar uma dúvida por exemplo.</p>
<p>Tutoriais escritos tem a vantagem de poder passar links externos no decorrer da leitura, facilitando o acesso à outras informações pelo usuário. Se eu mencionar um artigo de outro site, o leitor pode, instantaneamente, acessa-lo e revisar o conteúdo.</p>
<h2>O visual</h2>
<p>Não sou expert em design, aliás, estou bem longe disso, mas usei alguns conceitos que conheço pra tornar o site mais agradável para os usuários. <a href="http://www.webdesignerdepot.com/2009/12/minimalist-web-design-when-less-is-more/">Minimialismo</a> foi a palavra chave pra criação desse tema, focando puramente nos tutoriais, e deixando o resto em segundo plano.</p>
<p>A primeira grande mudança foi no esquema de cores. O tema antigo era bastante escuro, o que não é lá tão ruim pra um site que tem muitos vídeos, mas não é nada bom pra um site que tem muito texto (como este terá daqui por diante). Agora está tudo mais limpo e fácil de ler.</p>
<p>Usei a <a href="http://dev.opera.com/articles/view/setting-web-type-to-a-baseline-grid/">técnica do baseline</a>, pra leitura se <a href="http://www.alistapart.com/articles/settingtypeontheweb/">tornar ainda mais suave</a>. A fonte não está tão grande como antes, fazendo que a leitura fique menos cansativa. Também uso extensivamente cabeçalhos pra separar o conteúdo em partes lógicas e informar ao leitor o que está sendo feito em cada momento.</p>
<p>A estrutura está toda baseada em grids. <a href="http://articles.sitepoint.com/article/principles-beautiful-web-design/3">Grids conduzem o visitante</a> na leitura do conteúdo, e facilita seu entendimento, por estar bem estruturado. No caso específico desse blog usei o <a href="http://www.blueprintcss.org/">framework Blueprint</a>, porque acho mais <a href="http://speckyboy.com/2009/10/26/the-blueprint-css-framework-tutorials-how-to-guides-and-tools/">fácil e simples de usar</a>.</p>
<h2>Novidades</h2>
<p>Não há muitas novidades além das que já foram citadas anteriormente, mas gostaria de apontar algumas pequenas mudanças que tive todo cuidado pra que ficasse bem feitas.</p>
<h3>Comentários Agrupados</h3>
<p>A primeira que gostaria de falar é a possibilidade de <a href="http://bavotasan.com/tutorials/how-to-add-nested-comments-to-your-wordpress-theme/">responder diretamente aos comentários</a>, sem a necessidade do antigo <strong>@nome_do_usuario</strong>, que na minha opinião é algo horroroso, pois um comentário feito meses mais tarde pode responder a um comentário muito antigo e ficar bastante distante um do outro, sem muita relação visual. Com o novo sistema é possível responder diretamente, basta clicar em <em>responder</em> e pronto, a resposta ficará diretamente abaixo do comentário.</p>
<h3>Comentários em AJAX</h3>
<p>Agora os comentários são enviados em AJAX, o que é de grande comodidade caso você esteja assistindo a um vídeo e queira enviar um comentário sem precisar recarregar a página. O mesmo serve pra responder aos comentários, quando o botão de resposta é clicado, o formulário pula instantaneamente para o local onde o comentário se encontra, além de colocar o cursor do mouse diretamente no formulário, para que o usuário não precise usar o mouse para esta tarefa.</p>
<h3>Validação de comentários</h3>
<p>Outro cuidado que tomei foi validar os comentários antes do envio. Isso é bom para o usuário comum, porque mostra quando o email digitado não é válido ou quando ele esquecer de escrever um conteúdo por exemplo.</p>
<h3>Detalhes do tutorial</h3>
<p>Como última novidade gostaria de apontar os detalhes no início de cada tutorial. Agora antes de ler o conteúdo é possível saber o nível do tutorial e o tempo estimado para finalização. Os links pra download de arquivos, download do vídeo e preview online também se encontram neste local, unificando todos os dados sobre o tutorial.</p>
<h2>Velocidade</h2>
<p>Fiz questão de tornar esse blog o mais rápido possível em questão de tempo de carregamento. Usei praticamente todas as <a href="http://developer.yahoo.com/performance/rules.html">boas práticas recomendadas pelo time do Yahoo</a>. O <a href="http://developer.yahoo.com/yslow/">YSlow</a> deu rank A para este site, provando que cumpre muito bem as diretrizes do YSlow. No <a href="http://code.google.com/speed/page-speed/">Page Speed</a> ganhei uma pontuação de <em>85/100</em>, o que é um valor bastante expressivo.</p>
<h2>Conclusão</h2>
<p>Minha expectativa é que o Tutorial City tenha se tornado mais simples e rápido de usar. O conteúdo será o rei daqui por diante, com tutoriais de alto nível e bem detalhados. Espero que goste dessa nova fase e que sempre retorne para acompanhar os tutoriais. Um abraço e até a próxima!</p>
<img src="http://feeds.feedburner.com/~r/tutorial-city/XDvR/~4/mgEL68pnWBI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tutorial-city.net/noticias/redesign-do-tutorial-city/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://tutorial-city.net/noticias/redesign-do-tutorial-city/</feedburner:origLink></item>
		<item>
		<title>Como criar RSS com PHP e XMLWriter</title>
		<link>http://feedproxy.google.com/~r/tutorial-city/XDvR/~3/qWSK0U7rAm8/</link>
		<comments>http://tutorial-city.net/web/como-criar-rss-com-php-e-xmlwriter/#comments</comments>
		<pubDate>Sun, 15 Aug 2010 05:41:37 +0000</pubDate>
		<dc:creator>Tutorial City</dc:creator>
				<category><![CDATA[web]]></category>
		<category><![CDATA[pdo]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://tutorial-city.net/?p=688</guid>
		<description><![CDATA[RSS é um formato amplamente usado atualmente para distribuir conteúdo dinâmico na internet. Com a quantidade de informação disponível na web, se torna impraticável pensar em acessar cada site regularmente para saber se existe algo de novo. É exatamente aí &#8230; <a href="http://tutorial-city.net/web/como-criar-rss-com-php-e-xmlwriter/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>RSS é um formato amplamente usado atualmente para distribuir conteúdo dinâmico na internet. Com a quantidade de informação disponível na web, se torna impraticável pensar em acessar cada site regularmente para saber se existe algo de novo. É exatamente aí que a necessidade pelos feeds entra no jogo.<span id="more-688"></span></p>
<h2>O que é RSS?</h2>
<p>RSS nada mais é que um formato de distribuição de conteúdo baseado em XML, o que é ótimo, pois não exige que o desenvolvedor tenha que aprender uma nova linguagem para cria-lo.</p>
<p>Existem basicamente dois formatos principais de distribuição, que são <a href="http://en.wikipedia.org/wiki/Atom_(standard)">Atom</a>  e <a href="http://en.wikipedia.org/wiki/Rss">RSS</a>, que apresentam algumas diferenças entre si, mas o objetivo de ambos é o mesmo. O formato RSS tem duas ramificações, uma delas o RSS 1.0 e outra RSS 2.0 . Não vou abordar a diferença entre os dois neste tutorial, e usarei o ramo da versão 2.0, já que é bem mais simples e cumpre muito bem com seu dever.</p>
<h2>Criando RSS</h2>
<p>Neste tutorial usarei <em>XMLWriter</em> com PHP para escrever os arquivos de XML, mas você também pode usar a extensão <a href="http://gtivideoaulas.com/php-criando-xml-com-simplexml" rel="friend">SimpleXML para gerar XML </a>. Minha decisão pela extensão <em>XMLWriter</em> se deu pelo fato de eu acha-la bem mais simples e intuitiva para geração desse arquivo.</p>
<p>Sem mais delongas, vamos partir para a prática e ver como podemos gerar nosso próprio RSS.</p>
<h3>Estrutura</h3>
<p>A primeira coisa que temos que ter em mente é a estrutura do nosso RSS. Algumas tags  são obrigatórias, mas a maioria é opcional, nos dando maior flexibilidade de criação. Conforme descrito nas <a href="http://cyber.law.harvard.edu/rss/rss.html">especificações</a>, devemos iniciar nosso documento com uma tag chamada <em>rss</em> e dentro dessa tag devemos ter outra tag, chamada <em>channel</em>. Dentro da tag <em>channel</em> virão todas as informações sobre nosso RSS. Existem três tags obrigatórias dentro do <em>channel</em>, que são <em>title</em>, <em>link</em> e <em>description</em>. Abaixo você vê a estrutura mais básica possível de um RSS.</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;
&lt;rss version=&quot;2.0&quot;&gt;
	&lt;channel&gt;
		&lt;title&gt;TC - Feeds&lt;/title&gt;
		&lt;link&gt;http://localhost/tc/rss.xml&lt;/link&gt;
		&lt;description&gt;Blog que traz as novidades de desenvolvimento web&lt;/description&gt;
	&lt;/channel&gt;
&lt;/rss&gt;
</pre>
<p>
Tomei a liberdade de inserir um conteúdo qualquer, para que fique mais fácil identificar como é usado na prática. Neste momento o RSS já pode ser visualizado no navegador <em>(alguns navegadores  tem suporte de exibição e inscrição de feeds, mas isso não é uma regra. neste tutorial usei o Firefox para isso, mas existem vários interpretadores de RSS disponíveis, como o <a href="http://www.google.com.br/reader/">Google Reader</a> ou <a href="http://office.microsoft.com/pt-br/outlook/">Microsoft Outlook</a> por exemplo)</em>, apesar de não ter nenhum conteúdo. O resultado é mostrado abaixo.
</p>
<div class="image">
<img src="http://tutorial-city.net/wp-content/uploads/2010/08/1-firefox-basico.jpg" alt="" />
</div>
<h3>Conteúdo</h3>
<p>
Todo conteúdo do nosso RSS fica dentro da tag <em>item</em>, e podemos tem quantos itens nós quisermos, mas é comum que esse valor esteja entre cinco e vinte (normalmente 10).
</p>
<p>
A tag <em>item</em> não é obrigatória, mas dada a necessidade de distribuir conteúdo ela acaba se tornando mandatória. Não existe nenhuma tag exigida dentro da tag <em>item</em>, mas pelo menos uma deve existir.
</p>
<p>No caso específico desse tutorial irei usar as tags <em>title</em>, <em>link</em>, <em>description</em>, <em>guid</em> e <em>pubDate</em>. Em geral os nomes das tags se auto-explicam, mas de qualquer maneira deixo uma descrição simples a seguir:</p>
<dl>
<dt>title</dt>
<dd>Título do conteúdo</dd>
<dt>link</dt>
<dd>link do conteúdo</dd>
<dt>description</dt>
<dd>Conteúdo em si. particularmente acho interessante colocar somente uma introdução.</dd>
<dt>guid</dt>
<dd>Uma identificação única do conteúdo. Pode ter qualquer valor, desde que seja único.</dd>
<dt>pubDate</dt>
<dd>Data de publicação, no formato <em>RFC-822</em>. Existe uma constante que nos ajuda nessa situação, que é DATE_RSS.</dd>
</dl>
<p>com as informações acima já podemos iniciar a inserção de conteúdo no nosso XML.</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;
&lt;rss version=&quot;2.0&quot;&gt;
	&lt;channel&gt;
		&lt;title&gt;TC - Feeds&lt;/title&gt;
		&lt;link&gt;http://localhost/tc&lt;/link&gt;
		&lt;description&gt;Blog que traz as novidades de desenvolvimento web&lt;/description&gt;
		&lt;item&gt;
			&lt;title&gt;Primeiro Post&lt;/title&gt;
			&lt;link&gt;http://localhost/post/1&lt;/link&gt;
			&lt;description&gt;Este post fala sobre RSS&lt;/description&gt;
			&lt;guid&gt;http://localhost/post/1&lt;/guid&gt;
			&lt;pubDate&gt;Sat, 27 Feb 2010 15:13:53 +0000&lt;/pubDate&gt;
		&lt;/item&gt;
	&lt;/channel&gt;
&lt;/rss&gt;
</pre>
<p>visualizando no navegador, obtemos o seguinte resultado:</p>
<div class="image">
<img src="http://tutorial-city.net/wp-content/uploads/2010/08/2-firefox+com+item.jpg" alt="" />
</div>
<p>
Como pode-se ver, o navegador já percebeu que temos um item, e nos mostra na tela. A seguir vou criar outros dois itens para ver como ele se comporta. Repare como os itens se apresentam de forma decrescente, isso é importante por que sempre se deseja mostrar os mais recentes primeiro.
</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;
&lt;rss version=&quot;2.0&quot;&gt;
	&lt;channel&gt;
		&lt;title&gt;TC - Feeds&lt;/title&gt;
		&lt;link&gt;http://localhost/tc/rss.xml&lt;/link&gt;
		&lt;description&gt;Blog que traz as novidades de desenvolvimento web&lt;/description&gt;
		&lt;item&gt;
			&lt;title&gt;Primeiro Post&lt;/title&gt;
			&lt;link&gt;http://localhost/post/3&lt;/link&gt;
			&lt;description&gt;Este post fala ainda mais sobre RSS&lt;/description&gt;
			&lt;guid&gt;http://localhost/post/3&lt;/guid&gt;
			&lt;pubDate&gt;Mon, 01 Mar 2010 15:13:53 +0000&lt;/pubDate&gt;
		&lt;/item&gt;
		&lt;item&gt;
			&lt;title&gt;Segundo Post&lt;/title&gt;
			&lt;link&gt;http://localhost/post/2&lt;/link&gt;
			&lt;description&gt;Este post fala mais sobre RSS&lt;/description&gt;
			&lt;guid&gt;http://localhost/post/2&lt;/guid&gt;
			&lt;pubDate&gt;Sun, 28 Feb 2010 15:13:53 +0000&lt;/pubDate&gt;
		&lt;/item&gt;
		&lt;item&gt;
			&lt;title&gt;Primeiro Post&lt;/title&gt;
			&lt;link&gt;http://localhost/post/1&lt;/link&gt;
			&lt;description&gt;Este post fala sobre RSS&lt;/description&gt;
			&lt;guid&gt;http://localhost/post/1&lt;/guid&gt;
			&lt;pubDate&gt;Sat, 27 Feb 2010 15:13:53 +0000&lt;/pubDate&gt;
		&lt;/item&gt;
	&lt;/channel&gt;
&lt;/rss&gt;
</pre>
<div class="image">
<img src="http://tutorial-city.net/wp-content/uploads/2010/08/3-firefox+com+tres+itens.jpg" alt="" />
</div>
<p>
Com exceção da tag <em>item</em>, todos as tags que usei dentro de <em>channel</em> são obrigatórias. Agora vou inserir outras opcionais, que eu gosto de usar.
</p>
<pre class="brush: xml; highlight: [7,8,9,10,11,12,13,14,15];">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;
&lt;rss version=&quot;2.0&quot;&gt;
	&lt;channel&gt;
		&lt;title&gt;TC - Feeds&lt;/title&gt;
		&lt;link&gt;http://localhost/tc/rss.xml&lt;/link&gt;
		&lt;description&gt;Blog que traz as novidades de desenvolvimento web&lt;/description&gt;
		&lt;language&gt;pt&lt;/language&gt;
		&lt;pubDate&gt;Tue, 02 Mar 2010 14:43:32 +0000&lt;/pubDate&gt;
        &lt;image&gt;
            &lt;title&gt;TC - Feeds&lt;/title&gt;
            &lt;link&gt;http://www.localhost/tc&lt;/link&gt;
            &lt;url&gt;http://www.localhost/tc/tc.jpg&lt;/url&gt;
            &lt;width&gt;120&lt;/width&gt;
            &lt;height&gt;60&lt;/height&gt;
        &lt;/image&gt;
		&lt;item&gt;
			&lt;title&gt;Terceiro Post&lt;/title&gt;
			&lt;link&gt;http://localhost/post/3&lt;/link&gt;
			&lt;description&gt;Este post fala ainda mais sobre RSS&lt;/description&gt;
			&lt;guid&gt;http://localhost/post/3&lt;/guid&gt;
			&lt;pubDate&gt;Mon, 01 Mar 2010 15:13:53 +0000&lt;/pubDate&gt;
		&lt;/item&gt;
		&lt;item&gt;
			&lt;title&gt;Segundo Post&lt;/title&gt;
			&lt;link&gt;http://localhost/post/2&lt;/link&gt;
			&lt;description&gt;Este post fala mais sobre RSS&lt;/description&gt;
			&lt;guid&gt;http://localhost/post/2&lt;/guid&gt;
			&lt;pubDate&gt;Sun, 28 Feb 2010 15:13:53 +0000&lt;/pubDate&gt;
		&lt;/item&gt;
		&lt;item&gt;
			&lt;title&gt;Primeiro Post&lt;/title&gt;
			&lt;link&gt;http://localhost/post/1&lt;/link&gt;
			&lt;description&gt;Este post fala sobre RSS&lt;/description&gt;
			&lt;guid&gt;http://localhost/post/1&lt;/guid&gt;
			&lt;pubDate&gt;Sat, 27 Feb 2010 15:13:53 +0000&lt;/pubDate&gt;
		&lt;/item&gt;
	&lt;/channel&gt;
&lt;/rss&gt;
</pre>
<p>
As linhas destacadas foram inseridas. A descrição de cada um dos nós pode ser encontrada na <a href="http://cyber.law.harvard.edu/rss/rss.html">especificação RSS</a>.
</p>
<p>
Neste momento o RSS já foi criado, porém não faz muito sentido cria-lo manualmente, e é aí que entra o poder do <em>XMLWriter</em> no PHP.
</p>
<h2>Conhecendo o XMLWriter</h2>
<p>Usaremos somente alguns métodos do <em>XMLWriter</em>, e todos estão, brevemente, descritos a seguir. Para uma lista completa visite a <a href="http://br2.php.net/manual/pt_BR/book.xmlwriter.php">documentação oficial do XMLWriter</a></p>
<dl>
<dt>XMLWriter::openURI</dt>
<dd>Abre o arquivo que será usado para salvar o conteúdo do XML. Caso o arquivo não exista ele é criado. Se <em>php://output</em> for passado como parâmetro, o XML será jogado na tela</dd>
<dt>XMLWriter::startDocument</dt>
<dd>Inicia um documento</dd>
<dt>XMLWriter::endDocument</dt>
<dd>Finaliza um documento</dd>
<dt>XMLWriter::startElement</dt>
<dd>Inicia um elemento</dd>
<dt>XMLWriter::endElement</dt>
<dd>Finaliza um elemento</dd>
<dt>XMLWriter::writeElement</dt>
<dd>Escreve um elemento diretamente, sem a necessidade de fecha-lo posteriormente</dd>
<dt>XMLWriter::writeAttribute</dt>
<dd>Escreve um atributo no elemento mais recente.</dd>
<dt>XMLWriter::writeCData</dt>
<dd>Escreve um conteúdo escapado por CData (necessário quando se quer inserir HTML dentro de um arquivo XML)</dd>
<dt>XMLWriter::writeText</dt>
<dd>Escreve um texto dentro da tag mais recente</dd>
<dt>XMLWriter::flush</dt>
<dd>Salva o arquivo ou o joga na tela, dependendo do parâmetro passado para XMLWriter::openURI</dd>
</dl>
<h2>Organização das pastas e arquivos</h2>
<p>Organizarei minhas pastas da seguinte maneira</p>
<div class="image">
<img src="http://tutorial-city.net/wp-content/uploads/2010/08/4-estrutura+dos+arquivos.jpg" alt="" />
</div>
<h2>Banco de dados</h2>
<p>Para que tenhamos conteúdo para trabalhar, vou criar um banco de dados chamado <em>Blog</em>, e dentro desse banco de dados criarei uma tabela chamada <em>posts</em>. Esta tabela terá quatro campos, <em>id</em>, <em>titulo</em>, <em>conteudo</em> e <em>data_criacao</em>.</p>
<pre class="brush: sql;">
CREATE DATABASE Blog;
</pre>
<pre class="brush: sql;">
CREATE TABLE posts (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
  titulo VARCHAR(200) NOT NULL ,
  conteudo LONGTEXT NOT NULL ,
  data_criacao DATETIME NOT NULL
);
</pre>
<p>Agora basta inserir algum conteúdo</p>
<pre class="brush: sql;">
INSERT INTO posts VALUES
(NULL,'Primeiro Post','Conteúdo do primeiro post','2010-08-01 00:00:00'),
(NULL,'Segundo Post' ,'Conteúdo do segundo post' ,'2010-08-02 00:00:00'),
(NULL,'Terceiro Post','Conteúdo do terceiro post','2010-08-03 00:00:00'),
(NULL,'Quarto Post'  ,'Conteúdo do quarto post'  ,'2010-08-04 00:00:00'),
(NULL,'Quinto Post'  ,'Conteúdo do quinto post'  ,'2010-08-05 00:00:00')
</pre>
<h2>Conexão com banco de dados</h2>
<p>Primeiro vou criar o arquivo de conexão com o banco de dados, pois este será usado em algumas outras páginas. No arquivo <em>conexao.php</em> a conexão é criada. Usarei a extensão PDO para a interação com o banco de dados, caso você não saiba usa-la, pode aprender todo o <a href="http://tutorial-city.net/web/crud-com-prepared-statements-usando-pdo/" rel="me">CRUD com prepared statements usando PDO</a> neste tutorial aqui do Tutorial City.</p>
<pre class="brush: php;">
$host    = 'localhost';
$db_name = 'Blog';
$user    = 'root';
$pass    = '';

$dsn = 'mysql:host='.$host.';dbname='.$db_name;
try {
	$db = new PDO($dsn,$user,$pass);
	$db-&gt;setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
	unset($host);unset($db_name);unset($user);unset($pass);
} catch (PDOException $e) {
	echo $e-&gt;getMessage();
}
</pre>
<h2>Páginas</h2>
<h3>Página Inicial</h3>
<p>No arquivo <em>index.php</em>, localizado na raiz da nossa estrutura, vai ficar a lógica que mostrará todos os posts</p>
<pre class="brush: php; html-script: true;">
&lt;?php
require_once 'conexao.php';

//ordenar por data de criação de modo decrescente, para mostrar os mais recentes primeiro
$sql = 'SELECT id, titulo, conteudo, data_criacao FROM posts ORDER BY data_criacao DESC';
$query = $db-&gt;prepare($sql);
$query-&gt;execute();
$query-&gt;bindColumn('id'          ,$id			);
$query-&gt;bindColumn('titulo'      ,$titulo		);
$query-&gt;bindColumn('conteudo'    ,$conteudo		);
$query-&gt;bindColumn('data_criacao',$data_criacao );
$query-&gt;setFetchMode(PDO::FETCH_BOUND);
?&gt;
&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;pt-BR&quot;&gt;
&lt;head&gt;
	&lt;meta charset=&quot;utf-8&quot;&gt;
	&lt;title&gt;TC Blog&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
	&lt;?php while($query-&gt;fetch()):?&gt;
	&lt;h1&gt;&lt;?php echo utf8_encode($titulo)?&gt;&lt;/h1&gt;
	&lt;p&gt;&lt;em&gt;&lt;?php echo date('d/m/Y',strtotime($data_criacao))?&gt;&lt;/em&gt;&lt;/p&gt;
	&lt;p&gt;&lt;?php echo utf8_encode($conteudo)?&gt;&lt;/p&gt;
	&lt;p&gt;&lt;a href=&quot;http://localhost/tc/post.php?id=&lt;?php echo $id?&gt;&quot;&gt;Veja Mais&lt;/a&gt;&lt;/p&gt;
	&lt;hr /&gt;
	&lt;?php endwhile;?&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>Repare que usei a função <em>utf8_encode</em> no título e no conteúdo. Ela é necessária pois os caracteres acentuados não retornavam da maneira desejada. Visitando a página inicial temos o seguinte resultado:</p>
<div class="image">
<img src="http://tutorial-city.net/wp-content/uploads/2010/08/5-pagina+inicial.jpg" alt="" />
</div>
<h3>Post único</h3>
<p>
Agora vou criar a página do post único, que é bastante parecida com a página inicial, porém só pega um post.
</p>
<pre class="brush: php; html-script: true;">
&lt;?php
require_once 'conexao.php';

$sql = ' SELECT id, titulo, conteudo, data_criacao ';
$sql.= ' FROM posts';
$sql.= ' WHERE id = ?';
$query = $db-&gt;prepare($sql);
$query-&gt;bindValue(1,$_GET['id'],PDO::PARAM_INT);
$query-&gt;execute();
$query-&gt;bindColumn('id'          ,$id			);
$query-&gt;bindColumn('titulo'      ,$titulo		);
$query-&gt;bindColumn('conteudo'    ,$conteudo		);
$query-&gt;bindColumn('data_criacao',$data_criacao  );
$query-&gt;setFetchMode(PDO::FETCH_BOUND);
?&gt;
&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;pt-BR&quot;&gt;
&lt;head&gt;
	&lt;meta charset=&quot;utf-8&quot;&gt;
	&lt;title&gt;TC Blog&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
	&lt;?php $query-&gt;fetch()?&gt;
	&lt;h1&gt;&lt;?php echo utf8_encode($titulo)?&gt;&lt;/h1&gt;
	&lt;p&gt;&lt;em&gt;&lt;?php echo date('d/m/Y',strtotime($data_criacao))?&gt;&lt;/em&gt;&lt;/p&gt;
	&lt;p&gt;&lt;?php echo utf8_encode($conteudo)?&gt;&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<h2>Gerando XML usando XMLWriter</h2>
<p>Toda a base já está pronta nesse momento. Agora basta criar o RSS e inserir na página. Voltando ao arquivo <em>index.php</em> na pasta <em>rss</em>, vou iniciar a criação do XML usando <em>XMLWriter</em>.</p>
<pre class="brush: php;">
date_default_timezone_set('America/Sao_Paulo');
header('Content-type: application/rss+xml');

$rss = new XMLWriter();
$rss-&gt;openURI('php://output');
$rss-&gt;setIndent(true);
$rss-&gt;setIndentString('    ');

$rss-&gt;startDocument('1.0','utf-8');
	$rss-&gt;startElement('rss');
	$rss-&gt;writeAttribute('version','2.0');
		$rss-&gt;startElement('channel');
			$rss-&gt;writeElement('title','TC - Feeds');
			$rss-&gt;writeElement('link','http://localhost/tc');
			$rss-&gt;writeElement('description','Blog que traz as novidades de desenvolvimento web');
			$rss-&gt;writeElement('language','pt');
			$rss-&gt;writeElement('pubDate',date(DATE_RSS));
			$rss-&gt;startElement('image');
				$rss-&gt;writeElement('title','TC - Feeds');
				$rss-&gt;writeElement('link','http://localhost/tc');
				$rss-&gt;writeElement('url','http://localhost/tc/rss/tc.jpg');
				$rss-&gt;writeElement('width','120');
				$rss-&gt;writeElement('height','60');
			$rss-&gt;endElement();
		$rss-&gt;endElement();// final do channel
	$rss-&gt;endElement();// final do rss
$rss-&gt;endDocument();

//envia o xml para o endereço do openURI
$rss-&gt;flush();
</pre>
<p>Existem alguns pontos importantes a se destacar sobre o código acima. É uma boa prática usar a função <em>date_default_timezone_set</em> no documento, para que todas as datas sejam exibidas com fuso horário correto. É importante que se envie um cabeçalho dizendo que o conteúdo a seguir é RSS. Na linha cinco usei <em>php://output</em> como parâmetro do método <em>XMLWriter::openURI</em>, o que significa que eu quero que o conteúdo seja jogado na tela, e não em um arquivo. Nas linhas seis e sete digo que quero recuar meu código, e que usarei quatro espaços como recuo. Apesar disso não ser fundamental, é bom para que o código fique mais legível quando completo. O resto é bem simples, só crio tags e escrevo conteúdo conforme explicado no início do tutorial. Sempre tomo o cuidado de recuar meu código, para que eu saiba quem está dentro de quem, e recomendo que você faça o mesmo.</p>
<p>
Se dirigindo à URL <em>http://localhost/tc/rss</em>, o resultado é o seguinte:
</p>
<div class="image">
<img src="http://tutorial-city.net/wp-content/uploads/2010/08/6-rss+basico+usando+xmlwriter-.jpg" alt="" />
</div>
<h2>Gerando itens dinamicamente</h2>
<p>Agora basta inserir cada post dentro de um <em>item</em> no RSS. Primeiro inclui-se o arquivo de conexão no início do arquivo <em>index.php</em>, depois pega-se todos os posts, não esquecendo de ordenar de forma decrescente.</p>
<pre class="brush: php;">
&lt;?php 

require '../conexao.php';
$sql  = ' SELECT id, titulo, conteudo, data_criacao FROM posts ';
$sql .= ' ORDER BY data_criacao DESC LIMIT 10';
$query = $db-&gt;prepare($sql);
$query-&gt;execute();
$query-&gt;bindColumn('id'          ,$id			);
$query-&gt;bindColumn('titulo'      ,$titulo		);
$query-&gt;bindColumn('conteudo'    ,$conteudo		);
$query-&gt;bindColumn('data_criacao',$data_criacao  );
$query-&gt;setFetchMode(PDO::FETCH_BOUND);

date_default_timezone_set('America/Sao_Paulo');
header('Content-type: application/rss+xml');

$rss = new XMLWriter();
$rss-&gt;openURI('php://output');
$rss-&gt;setIndent(true);
$rss-&gt;setIndentString('    ');

$rss-&gt;startDocument('1.0','utf-8');
	$rss-&gt;startElement('rss');
	$rss-&gt;writeAttribute('version','2.0');
		$rss-&gt;startElement('channel');
			$rss-&gt;writeElement('title','TC - Feeds');
			$rss-&gt;writeElement('link','http://localhost/tc');
			$rss-&gt;writeElement('description','Blog que traz as novidades de desenvolvimento web');
			$rss-&gt;writeElement('language','pt');
			$rss-&gt;writeElement('pubDate',date(DATE_RSS));
			$rss-&gt;startElement('image');
				$rss-&gt;writeElement('title','TC - Feeds');
				$rss-&gt;writeElement('link','http://localhost/tc');
				$rss-&gt;writeElement('url','http://localhost/tc/rss/tc.jpg');
				$rss-&gt;writeElement('width','120');
				$rss-&gt;writeElement('height','60');
			$rss-&gt;endElement();
/***************** ITEM *****************/
			while($query-&gt;fetch()):
			$rss-&gt;startElement('item');
				$rss-&gt;writeElement('title',utf8_encode($titulo));
				$rss-&gt;writeElement('link','http://localhost/tc/post.php?id='.$id);
				$rss-&gt;startElement('description');
					$rss-&gt;writeCData(utf8_encode($conteudo));
				$rss-&gt;endElement();
				$rss-&gt;writeElement('guid','http://localhost/tc/post.php?id='.$id);
				$rss-&gt;writeElement('pubDate',date(DATE_RSS,strtotime($data_criacao)));
			$rss-&gt;endElement();
			endwhile;
/***************************************/
		$rss-&gt;endElement();// final do channel
	$rss-&gt;endElement();//final do rss
$rss-&gt;endDocument();

//envia o xml para o endereço do openURI
$rss-&gt;flush();
</pre>
<p>Repare que para escrever o conteúdo eu usei o método <em>XMLWriter::writeCData</em>, pois o conteúdo pode apresentar tags HTML, e estas não podem vir diretamente em um arquivo XML, tendo que ser escapadas usando CData.</p>
<p>Visualizando o código no navegador temos o seguinte:</p>
<div class="image">
<img src="http://tutorial-city.net/wp-content/uploads/2010/08/7-rss+usando+xmlwriter.jpg" alt="" />
</div>
<p><P>Para mostrar como pode-se inserir HTML no conteúdo, vou modificar o conteúdo do segundo post</p>
<pre class="brush: sql;">
UPDATE posts
SET conteudo = `&lt;h3&gt;conteúdo&lt;/h3&gt; do &lt;code&gt;segundo&lt;/code&gt; post`
WHERE id = 2;
</pre>
<p>Agora voltando ao RSS, o resultado é o seguinte:</p>
<div class="image">
<img src="http://tutorial-city.net/wp-content/uploads/2010/08/8-rss+usando+xmlwriter+com+html.jpg" alt="" />
</div>
<h2>Criando a referência do RSS no HTML</h2>
<p>Neste momento tudo já está pronto, e já podemos assinar nosso RSS. Os navegadores mais recentes exibem um ícone na barra de endereços indicando quando um site tem conteúdo RSS, mas isso não acontece automaticamente, até por que o navegador não sabe se você tem um arquivo pra isso, a menos que você diga a ele que você tem RSS para disponibilizar. Para fazer isso basta adicionar uma linha ao cabeçalho do nosso HTML, como visto a seguir:</p>
<pre class="brush: xml; highlight: [4];">
&lt;head&gt;
	&lt;meta charset=&quot;utf-8&quot;&gt;
	&lt;title&gt;TC Blog&lt;/title&gt;
	&lt;link rel=&quot;alternate&quot; type=&quot;application/rss+xml&quot; title=&quot;RSS&quot; href=&quot;http://localhost/tc/rss&quot; /&gt;
&lt;/head&gt;
</pre>
<p>Agora olhando para a barra de endereços vemos um ícone de RSS, indicando que o site apresenta conteúdo no formato RSS.</p>
<div class="image">
<img src="http://tutorial-city.net/wp-content/uploads/2010/08/9-icones+de+rssl.jpg" alt="" />
</div>
<h2>Validação</h2>
<p>O último passo é validar nosso RSS. Para isso basta visitar o <a href="http://validator.w3.org/feed/">site oficial do validador</a>. Como meu conteúdo está offline, no meu servidor local, tenho que selecionar a opção de jogar o RSS diretamente na tela (segunda aba). Para coletar nosso XML basta acessar <em>http://localhost/tc/rss</em> e usar o atalho <em>CTRL + U</em> no Firefox, para ter acesso ao código fonte. Daí basta copiar e colar no validador. o resultado no meu caso foi o seguinte:</p>
<div class="image">
<img src="http://tutorial-city.net/wp-content/uploads/2010/08/10-nao+validando+.jpg" alt="" />
</div>
<p><P>O RSS validou, mas o validador recomenda que usemos <em>rel=&#8221;self&#8221;</em>, que nada mais é que uma referência ao próprio arquivo de RSS. Isto é importante para que os diversos leitores consigam entender melhor nosso feed.</p>
<p>Voltando ao nosso <em>index.php</em> na pasta <em>rss</em>, modifiquei as linhas marcadas, para atender ao pedido do validador</p>
<pre class="brush: php; highlight: [22,25,26,27,28,29];">
require '../conexao.php';
$sql  = ' SELECT id, titulo, conteudo, data_criacao FROM posts ';
$sql .= ' ORDER BY data_criacao DESC LIMIT 10';
$query = $db-&gt;prepare($sql);
$query-&gt;execute();
$query-&gt;bindColumn('id'          ,$id			);
$query-&gt;bindColumn('titulo'      ,$titulo		);
$query-&gt;bindColumn('conteudo'    ,$conteudo		);
$query-&gt;bindColumn('data_criacao',$data_criacao );
$query-&gt;setFetchMode(PDO::FETCH_BOUND);

date_default_timezone_set('America/Sao_Paulo');
header('Content-type: application/rss+xml');

$rss = new XMLWriter();
$rss-&gt;openURI('php://output');
$rss-&gt;setIndent(true);
$rss-&gt;setIndentString('    ');

$rss-&gt;startDocument('1.0','utf-8');
	$rss-&gt;startElement('rss');
	$rss-&gt;writeAttribute('xmlns:atom','http://www.w3.org/2005/Atom');
	$rss-&gt;writeAttribute('version','2.0');
		$rss-&gt;startElement('channel');
			$rss-&gt;startElement('atom:link');
			$rss-&gt;writeAttribute('rel','self');
			$rss-&gt;writeAttribute('type','application/rss+xml');
			$rss-&gt;writeAttribute('href','http://localhost/tc/rss/');
			$rss-&gt;endElement();
			$rss-&gt;writeElement('title','TC - Feeds');
			$rss-&gt;writeElement('link','http://localhost/tc');
			$rss-&gt;writeElement('description','Blog que traz as novidades de desenvolvimento web');
			$rss-&gt;writeElement('language','pt');
			$rss-&gt;writeElement('pubDate',date(DATE_RSS));
			$rss-&gt;startElement('image');
				$rss-&gt;writeElement('title','TC - Feeds');
				$rss-&gt;writeElement('link','http://localhost/tc');
				$rss-&gt;writeElement('url','http://localhost/tc/rss/tc.jpg');
				$rss-&gt;writeElement('width','120');
				$rss-&gt;writeElement('height','60');
			$rss-&gt;endElement();
/***************** ITEM *****************/
			while($query-&gt;fetch()):
			$rss-&gt;startElement('item');
				$rss-&gt;writeElement('title',utf8_encode($titulo));
				$rss-&gt;writeElement('link','http://localhost/tc/post.php?id='.$id);
				$rss-&gt;startElement('description');
					$rss-&gt;writeCData(utf8_encode($conteudo));
				$rss-&gt;endElement();
				$rss-&gt;writeElement('guid','http://localhost/tc/post.php?id='.$id);
				$rss-&gt;writeElement('pubDate',date(DATE_RSS,strtotime($data_criacao)));
			$rss-&gt;endElement();
			endwhile;
/***************************************/
		$rss-&gt;endElement();// final do channel
	$rss-&gt;endElement();//final do rss
$rss-&gt;endDocument();

//envia o xml para o endereço do openURI
$rss-&gt;flush();
</pre>
<p>O efeito das mudanças no código fonte é mostrado abaixo:</p>
<pre class="brush: xml; highlight: [2,4];">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;rss xmlns:atom=&quot;http://www.w3.org/2005/Atom&quot; version=&quot;2.0&quot;&gt;
    &lt;channel&gt;
        &lt;atom:link rel=&quot;self&quot; type=&quot;application/rss+xml&quot; href=&quot;http://localhost/tc/rss/&quot;/&gt;
        &lt;title&gt;TC - Feeds&lt;/title&gt;
        &lt;link&gt;http://localhost/tc&lt;/link&gt;
        &lt;description&gt;Blog que traz as novidades de desenvolvimento web&lt;/description&gt;
        &lt;language&gt;pt&lt;/language&gt;
        &lt;pubDate&gt;Sat, 14 Aug 2010 19:45:14 -0300&lt;/pubDate&gt;
</pre>
<p>Voltando ao validador e refazendo o teste veremos que outro erro ocorrerá, dizendo que o arquivo não foi encontrado no endereço que passamos. Esse erro só acontece porque o arquivo está offline, e o validador não consegue acessá-lo. Quando o RSS ficar online vai estar 100% validado e pronto pra ser usado.</p>
<h2>Conclusão</h2>
<p>Neste momento você já é capaz de criar feeds RSS em seus sites, tornando-os muito mais ricos. Existe muito sobre RSS que não foi mencionado nesse tutorial, então te encorajo a pesquisar sobre o assunto. usando <em>XMLWriter</em> é muito fácil criar qualquer arquivo XML, mas existem vários métodos que não usei, e também recomendo que dê uma lida na documentação oficial para se tornar ainda melhor.</p>
<p>Agradeço por ter seguido todo o tutorial, e não se esqueça de fazer perguntas caso tenha alguma dúvida. Até a próxima!</p>
<img src="http://feeds.feedburner.com/~r/tutorial-city/XDvR/~4/qWSK0U7rAm8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tutorial-city.net/web/como-criar-rss-com-php-e-xmlwriter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://tutorial-city.net/web/como-criar-rss-com-php-e-xmlwriter/</feedburner:origLink></item>
		<item>
		<title>Chaining no PHP</title>
		<link>http://feedproxy.google.com/~r/tutorial-city/XDvR/~3/The9GhRiExU/</link>
		<comments>http://tutorial-city.net/web/chaining-no-php/#comments</comments>
		<pubDate>Mon, 29 Mar 2010 00:16:06 +0000</pubDate>
		<dc:creator>Tutorial City</dc:creator>
				<category><![CDATA[web]]></category>
		<category><![CDATA[chaining]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://tutorial-city.net/?p=537</guid>
		<description><![CDATA[Neste tutorial você aprenderá uma técnica bastante útil em PHP, chamada Chaining.Esta técnica é usada vastamente em outras linguagens, como javascript, porém em PHP ela é muito menos usada do que deveria. swfobject.embedSWF("http://blip.tv/play/AYHLsGsA","video-1","640","430","9.0.28",'',{},{'allowscriptaccess':'always','allowfullscreen':'true'});]]></description>
			<content:encoded><![CDATA[<p>Neste tutorial você aprenderá uma técnica bastante útil em PHP, chamada Chaining.<span id="more-537"></span>Esta técnica é usada vastamente em outras linguagens, como javascript, porém em PHP ela é muito menos usada do que deveria.</p>
<div class="video"><script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script><script type="text/javascript">swfobject.embedSWF("http://blip.tv/play/AYHLsGsA","video-1","640","430","9.0.28",'',{},{'allowscriptaccess':'always','allowfullscreen':'true'});</script>
<div id="video-1"></div>
</div>
<img src="http://feeds.feedburner.com/~r/tutorial-city/XDvR/~4/The9GhRiExU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tutorial-city.net/web/chaining-no-php/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
<enclosure url="http://blip.tv/file/get/Tutorialcity-ChainingNoPHP681.mp4" length="13022053" type="video/mp4" />
		<media:content url="http://blip.tv/file/get/Tutorialcity-ChainingNoPHP681.mp4" fileSize="13022053" type="video/mp4" /><itunes:explicit>no</itunes:explicit><itunes:subtitle>Neste tutorial você aprenderá uma técnica bastante útil em PHP, chamada Chaining.Esta técnica é usada vastamente em outras linguagens, como javascript, porém em PHP ela é muito menos usada do que deveria. swfobject.embedSWF("http://blip.tv/play/AYHLsGsA",</itunes:subtitle><itunes:summary>Neste tutorial você aprenderá uma técnica bastante útil em PHP, chamada Chaining.Esta técnica é usada vastamente em outras linguagens, como javascript, porém em PHP ela é muito menos usada do que deveria. swfobject.embedSWF("http://blip.tv/play/AYHLsGsA","video-1","640","430","9.0.28",'',{},{'allowscriptaccess':'always','allowfullscreen':'true'});</itunes:summary><itunes:keywords>web, chaining, php</itunes:keywords><feedburner:origLink>http://tutorial-city.net/web/chaining-no-php/</feedburner:origLink></item>
		<item>
		<title>Pegando favoritos do Delicious e Estilizando com CSS3</title>
		<link>http://feedproxy.google.com/~r/tutorial-city/XDvR/~3/Czbg5ZxoKWk/</link>
		<comments>http://tutorial-city.net/web/pegando-favoritos-do-delicious-e-estilizando-com-css3/#comments</comments>
		<pubDate>Sat, 27 Feb 2010 15:13:53 +0000</pubDate>
		<dc:creator>Tutorial City</dc:creator>
				<category><![CDATA[web]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://tutorial-city.net/?p=518</guid>
		<description><![CDATA[Delicious é uma comunidade que todo webdesigner deveria conhecer. É um site que armazena e compartilha seus favoritos, facilitando as buscas e te poupando o trabalho de sempre tem de fazer backup dos links do site ou tutoriais que gosta. &#8230; <a href="http://tutorial-city.net/web/pegando-favoritos-do-delicious-e-estilizando-com-css3/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Delicious é uma comunidade que todo webdesigner deveria conhecer. É um site que armazena e compartilha seus favoritos, facilitando as buscas e te poupando o trabalho de sempre tem de fazer backup dos links do site ou tutoriais que gosta. Neste tutorial mostro como pegar seus favoritos (ou de qualquer outro usuário) usando jQuery e estilizar usando várias técnicas de CSS3.<br />
<span id="more-518"></span></p>
<div class="video"><script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script><script type="text/javascript">swfobject.embedSWF("http://blip.tv/play/AYHFuH4A","video-1","640","430","9.0.28",'',{},{'allowscriptaccess':'always','allowfullscreen':'true'});</script>
<div id="video-1"></div>
</div>
<img src="http://feeds.feedburner.com/~r/tutorial-city/XDvR/~4/Czbg5ZxoKWk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tutorial-city.net/web/pegando-favoritos-do-delicious-e-estilizando-com-css3/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
<enclosure url="http://blip.tv/file/get/Tutorialcity-PegandoLinksDoDeliciousEEstilizandoComCSS3691.mp4" length="58290721" type="video/mp4" />
		<media:content url="http://blip.tv/file/get/Tutorialcity-PegandoLinksDoDeliciousEEstilizandoComCSS3691.mp4" fileSize="58290721" type="video/mp4" /><itunes:explicit>no</itunes:explicit><itunes:subtitle>Delicious é uma comunidade que todo webdesigner deveria conhecer. É um site que armazena e compartilha seus favoritos, facilitando as buscas e te poupando o trabalho de sempre tem de fazer backup dos links do site ou tutoriais que gosta. &amp;#8230; Continue </itunes:subtitle><itunes:summary>Delicious é uma comunidade que todo webdesigner deveria conhecer. É um site que armazena e compartilha seus favoritos, facilitando as buscas e te poupando o trabalho de sempre tem de fazer backup dos links do site ou tutoriais que gosta. &amp;#8230; Continue reading &amp;#8594;</itunes:summary><itunes:keywords>web, css, css3, jquery</itunes:keywords><feedburner:origLink>http://tutorial-city.net/web/pegando-favoritos-do-delicious-e-estilizando-com-css3/</feedburner:origLink></item>
		<item>
		<title>CRUD com Prepared Statements usando PDO</title>
		<link>http://feedproxy.google.com/~r/tutorial-city/XDvR/~3/YA8NG_vAJsc/</link>
		<comments>http://tutorial-city.net/web/crud-com-prepared-statements-usando-pdo/#comments</comments>
		<pubDate>Thu, 11 Feb 2010 19:10:00 +0000</pubDate>
		<dc:creator>Tutorial City</dc:creator>
				<category><![CDATA[web]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[pdo]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://tutorial-city.net/?p=504</guid>
		<description><![CDATA[Neste tutorial você vai aprender a Create(Criar), Read(Ler), Update(Atualizar) e Delete(Deletar) informações do banco de dados usando a classe PDO e a técnica de prepared statements. A classe PDO é muito mais rápida e segura que que a extensão mysql_, &#8230; <a href="http://tutorial-city.net/web/crud-com-prepared-statements-usando-pdo/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Neste tutorial você vai aprender a  <em>Create</em>(Criar), <em>Read</em>(Ler), <em>Update</em>(Atualizar) e <em>Delete</em>(Deletar) informações do banco de dados usando a classe PDO e a técnica de prepared statements. A classe PDO é muito mais rápida e segura que que a extensão mysql_, por isso a preferência pelo seu uso. A técnica de prepared statements é uma forma mais segura de se manipular o banco de dados, pois impede toda e qualquer forma de SQL Injection.<span id="more-504"></span> Confira nos vídeos abaixo como você pode se atualizar e escrever um script muito melhor.</p>
<h3>Estabelecendo uma conexão</h3>
<div class="video"><script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script><script type="text/javascript">swfobject.embedSWF("http://vimeo.com/moogaloop.swf","video-1","640","400","9.0.28",'',{'clip_id': 9362457,'server': 'vimeo.com','show_title': 1,'show_byline': 1,'show_portrait': 0,'color': '00ADEF','fullscreen': 1,'js_api': 1},{'bgcolor':'#ffffff','allowscriptaccess':'always','allowfullscreen':'true','scalemode':'showall','quality':'high','opaque':'wmode'});</script>
<div id="video-1"></div>
</div>
<h3>Inserindo Dados</h3>
<div class="video"></script><script type="text/javascript">swfobject.embedSWF("http://vimeo.com/moogaloop.swf","video-2","640","400","9.0.28",'',{'clip_id': 9363642,'server': 'vimeo.com','show_title': 1,'show_byline': 1,'show_portrait': 0,'color': '00ADEF','fullscreen': 1,'js_api': 1},{'bgcolor':'#ffffff','allowscriptaccess':'always','allowfullscreen':'true','scalemode':'showall','quality':'high','opaque':'wmode'});</script>
<div id="video-2"></div>
</div>
<h3>Atualizando Dados</h3>
<div class="video"></script><script type="text/javascript">swfobject.embedSWF("http://vimeo.com/moogaloop.swf","video-3","640","400","9.0.28",'',{'clip_id': 9362724,'server': 'vimeo.com','show_title': 1,'show_byline': 1,'show_portrait': 0,'color': '00ADEF','fullscreen': 1,'js_api': 1},{'bgcolor':'#ffffff','allowscriptaccess':'always','allowfullscreen':'true','scalemode':'showall','quality':'high','opaque':'wmode'});</script>
<div id="video-3"></div>
</div>
<h3>Deletando Dados</h3>
<div class="video"><script type="text/javascript">swfobject.embedSWF("http://vimeo.com/moogaloop.swf","video-4","640","400","9.0.28",'',{'clip_id': 9355259,'server': 'vimeo.com','show_title': 1,'show_byline': 1,'show_portrait': 0,'color': '00ADEF','fullscreen': 1,'js_api': 1},{'bgcolor':'#ffffff','allowscriptaccess':'always','allowfullscreen':'true','scalemode':'showall','quality':'high','opaque':'wmode'});</script>
<div id="video-4"></div>
</div>
<h3>Lendo Dados</h3>
<div class="video"></script><script type="text/javascript">swfobject.embedSWF("http://vimeo.com/moogaloop.swf","video-5","640","400","9.0.28",'',{'clip_id': 9364983,'server': 'vimeo.com','show_title': 1,'show_byline': 1,'show_portrait': 0,'color': '00ADEF','fullscreen': 1,'js_api': 1},{'bgcolor':'#ffffff','allowscriptaccess':'always','allowfullscreen':'true','scalemode':'showall','quality':'high','opaque':'wmode'});</script>
<div id="video-5"></div>
</div>
<h3>Códigos digitados nos vídeos</h3>
<ul>
<li><a href="http://pastebin.com/f9bd4f89">Código do arquivo config.php</a></li>
<li><a href="http://pastebin.com/f24c90b05">Código do arquivo create.php</a></li>
<li><a href="http://pastebin.com/f1f9afbb2">Código do arquivo update.php</a></li>
<li><a href="http://pastebin.com/f535c6f11">Código do arquivo delete.php</a></li>
<li><a href="http://pastebin.com/f20902126">Código do arquivo read.php</a></li>
</ul>
<img src="http://feeds.feedburner.com/~r/tutorial-city/XDvR/~4/YA8NG_vAJsc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tutorial-city.net/web/crud-com-prepared-statements-usando-pdo/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		<feedburner:origLink>http://tutorial-city.net/web/crud-com-prepared-statements-usando-pdo/</feedburner:origLink></item>
		<item>
		<title>Criando um Plugin de Marca D’água com jQuery</title>
		<link>http://feedproxy.google.com/~r/tutorial-city/XDvR/~3/8pt4Hl8dFJ8/</link>
		<comments>http://tutorial-city.net/web/criando-um-plugin-de-marca-dagua-com-jquery/#comments</comments>
		<pubDate>Tue, 15 Sep 2009 09:00:25 +0000</pubDate>
		<dc:creator>Tutorial City</dc:creator>
				<category><![CDATA[web]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[plugin]]></category>

		<guid isPermaLink="false">http://tutorial-city.net/?p=464</guid>
		<description><![CDATA[Neste tutorial você irá aprender a criar um plugin para jQuery que insere uma marca d&#8217;água em inputs do tipo text e textarea. swfobject.embedSWF("http://vimeo.com/moogaloop.swf","video-1","640","400","9.0.28",'',{'clip_id': 6600106,'server': 'vimeo.com','show_title': 1,'show_byline': 1,'show_portrait': 0,'color': '00ADEF','fullscreen': 1,'js_api': 1},{'bgcolor':'#ffffff','allowscriptaccess':'always','allowfullscreen':'true','scalemode':'showall','quality':'high','opaque':'wmode'}); O primeiro passo é criar um arquivo javascript. &#8230; <a href="http://tutorial-city.net/web/criando-um-plugin-de-marca-dagua-com-jquery/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Neste tutorial você irá aprender a criar um plugin para jQuery que insere uma marca d&#8217;água em inputs do tipo text e textarea. <span id="more-464"></span></p>
<div class="video"><script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script><script type="text/javascript">swfobject.embedSWF("http://vimeo.com/moogaloop.swf","video-1","640","400","9.0.28",'',{'clip_id': 6600106,'server': 'vimeo.com','show_title': 1,'show_byline': 1,'show_portrait': 0,'color': '00ADEF','fullscreen': 1,'js_api': 1},{'bgcolor':'#ffffff','allowscriptaccess':'always','allowfullscreen':'true','scalemode':'showall','quality':'high','opaque':'wmode'});</script>
<div id="video-1"></div>
</div>
<p>O primeiro passo é criar um arquivo javascript. Uma sugestão de nome é <em>jquery.{nome do plugin}.js</em>, então no meu caso vou nomear o arquivo <em>jquery.watermark.js</em>.</p>
<p>Várias bibliotecas/frameworks de javascript dão ao símbolo <em>$</em> uma função especial, e isotp não é diferente para jQuery, então o primeiro passo é evitar que este conflito ocorra. Para isso devemos iniciar nosso plugin com uma função anônima autoexecutável, passando o parâmetro <em>jQuery</em> e transformando-o em <em>$</em>, como no código abaixo.</p>
<pre class="brush: jscript;">
(function($){
//Todo o código que compõe o plugin deve ficar aqui.
})(jQuery);
</pre>
<p>Em seguida devemos mencionar que estamos iniciando um plugin, então escrevemos o seguinte
<pre class="brush: jscript;">
(function($){

	$.fn.watermark = function(){
		//Aqui vem os parâmetros e as funções que compõem o plugin.
	}

})(jQuery);
</pre>
<p>Agora devemos decidir se nosso plugin terá parâmetros ou não. Neste caso eu adicionarei alguns parâmetros, são eles:</p>
<ol>
<li>corMarcaDagua</li>
<li>estiloMarcaDagua</li>
<li>corTexto</li>
<li>estiloTexto</li>
<li>valorPadrao</li>
</ol>
<p>estes parâmetros me darão a cor e o estilo da marca d&#8217;água, a cor e o estilo do texto que é digitado, e o valor padrão do input ou textarea que não tiver valor especificado. </p>
<pre class="brush: jscript;">
(function($){

	$.fn.watermark = function(parametros){
		//Aqui vem os parâmetros e a funções que compõem o plugin.
	}

})(jQuery);
</pre>
<p>A variável parâmetros será um objeto passado para o plugin. Caso o usuário não passe nenhum valor o plugin deve estar preparado para usar valores padrões, por isso crio um objeto que será usado para este fim.</p>
<pre class="brush: jscript;">
(function($){

	$.fn.watermark = function(parametros){
		var padroes = {
				 corMarcaDagua    : '#bbbbbb'
				,estiloMarcaDagua : 'italic'
				,corTexto         : '#000000'
				,estiloTexto      : 'normal'
				,valorPadrao      : 'pesquisar...'
			}

			//O plugin continua aqui...
	}

})(jQuery);
</pre>
<p>O plugin deve usar os valores padrões caso o usuário não passe nenhum valor, mas caso seja passado o plugin deve usar os valores do usuário. Para isto acontecer devemos estender os valores padrões e mescla-los com os valores do usuário. Abaixo vê-se como criar chegar a este fim</p>
<pre class="brush: jscript;">
function($){

	$.fn.watermark = function(parametros){
		var  padroes = {
				 corMarcaDagua    : '#bbbbbb'
				,estiloMarcaDagua : 'italic'
				,corTexto         : '#000000'
				,estiloTexto      : 'normal'
				,valorPadrao      : 'pesquisar...'
			}

		padrao = $.extend({},padroes,parametros);

		//O plugin continua aqui...
	}

})(jQuery);
</pre>
<p>A função <em>$.extend()</em> tem 3 parâmetros. O primeiro é um objeto vazio, o segundo é a variável com os padrões do plugin, e o terceiro é o objeto passado pelo usuário. Repare como a variável <em>padrao</em> agora se torna os parâmetros que o usuário passar, ou assume os valores padrões que criamos, caso o usuário não passe nada.</p>
<p>O próximo passo é criar a(s) função(s) que deve ser executada para <strong>CADA</strong>(each) elemento que for atingido com o seletor de jQuery.</p>
<pre class="brush: jscript;">
(function($){

	$.fn.watermark = function(parametros){
		var padroes = {
				 corMarcaDagua    : '#bbbbbb'
				,estiloMarcaDagua : 'italic'
				,corTexto         : '#000000'
				,estiloTexto      : 'normal'
				,valorPadrao      : 'pesquisar...'
			}

		padrao = $.extend({},padroes,parametros);

		return this.each(function(){
			//Todos os elementos que forem atingidos com
			//o seletor do jQuery sofrerão com o que vier
			//aqui dentro.
		});

	}

})(jQuery);
</pre>
<p>Repare que usei <em>return</em> antes de <em>this.each()</em>. Isto não é estritamente necessário, mas é altamente recomendável, para que nosso plugin permita <em>chaining</em> no jQuery.</p>
<p>No começo eu disse que o plugin seria limitado a inputs do tipo texto e textarea, porém o plugin ainda não sabe da minha intenção, então tenho que dizer explicitamente que quero isso. em jQuery usamos o método <em>is()</em> para descobrir com qual elementos estamos trabalhando.</p>
<pre class="brush: jscript;">
(function($){

	$.fn.watermark = function(parametros){
		var padroes = {
				 corMarcaDagua    : '#bbbbbb'
				,estiloMarcaDagua : 'italic'
				,corTexto         : '#000000'
				,estiloTexto      : 'normal'
				,valorPadrao      : 'pesquisar...'
			}

		padrao = $.extend({},padroes,parametros);

		return this.each(function(){

			if($(this).is('input:text') || $(this).is('textarea') ){
				//Aqui ficarão as ações que serão executadas
				//em todos os input's e textarea's que forem
				//atingidos com nosso seletor de jQuery
			}

		});

	}

})(jQuery);
</pre>
<p>Repare que filtrei os inputs do tipo texto somente escrevendo &#8216;:text&#8217;, mas eu poderia alternativamente usar a sintaxe de CSS <em>input[type=text]</em>.</p>
<p>até este momento usei o elemento <em>$(this)</em> mais de uma vez, então é uma boa ideia usar uma variável que tenha o mesmo valor dele, para armazena-lo em cache e tornar nosso script mais rápido. Vou chamar a variável de <em>$elemento</em>, para ficar claro que ele representará cada elemento. Também coloco um cifrão no começo, para que fique claro que estou mexendo com um objeto do jQuery.</p>
<pre class="brush: jscript;">
(function($){

	$.fn.watermark = function(parametros){
		var padroes = {
				 corMarcaDagua    : '#bbbbbb'
				,estiloMarcaDagua : 'italic'
				,corTexto         : '#000000'
				,estiloTexto      : 'normal'
				,valorPadrao      : 'pesquisar...'
			}

		padrao = $.extend({},padroes,parametros);

		return this.each(function(){

			$elemento = $(this);

			if($elemento.is('input:text') || $elemento.is('textarea') ){
				//Aqui ficarão as ações que serão executadas
				//em todos os input's e textarea's que forem
				//atinigidos com nosso seletor de jQuery
			}

		});

	}

})(jQuery);
</pre>
<p>Quando iniciamos o plugin queremos que o valor padrão que aparece nos input&#8217;s e textarea&#8217;s esteja na forma de marca d&#8217;água, então devemos dar a ele a cor de marca d&#8217;água e o estilo de marca d&#8217;água. Para isso usamos o método <em>css()</em> em todos os elementos usando a variável <em>$elemento</em>.</p>
<pre class="brush: jscript;">
(function($){

	$.fn.watermark = function(parametros){
		var  padroes = {
				 corMarcaDagua    : '#bbbbbb'
				,estiloMarcaDagua : 'italic'
				,corTexto         : '#000000'
				,estiloTexto      : 'normal'
				,valorPadrao      : 'pesquisar...'
			}

		padrao = $.extend({},padroes,parametros);

		return this.each(function(){

			$elemento = $(this);

			if($elemento.is('input:text') || $elemento.is('textarea') ){

				$elemento.css({
					 color     : padrao.corMarcaDagua
					,fontStyle: padrao.estiloMarcaDagua
				});

			}

		});

	}

})(jQuery);
</pre>
<p>Em seguida temos de descobrir uma maneira de guardar os valores padrões dos input&#8217;s e textarea&#8217;s. Escolhi guarda-lo no atributo <em>rel</em>, que será criado dinamicamente com o script.<br />
Caso o input tenha um valor no HTML, o usaremos, caso contrário usaremos o que será passado ao plugin pelo usuário, se nada for passado usaremos o padrão do plugin(&#8216;pesquisar&#8230;&#8217;).</p>
<pre class="brush: jscript;">
(function($){

	$.fn.watermark = function(parametros){
		var  padroes = {
				 corMarcaDagua    : '#bbbbbb'
				,estiloMarcaDagua : 'italic'
				,corTexto         : '#000000'
				,estiloTexto      : 'normal'
				,valorPadrao      : 'pesquisar...'
			}

		padrao = $.extend({},padroes,parametros);

		return this.each(function(){

			$elemento = $(this);

			if($elemento.is('input:text') || $elemento.is('textarea') ){

				$elemento.css({
					 color     : padrao.corMarcaDagua
					,fontStyle : padrao.estiloMarcaDagua
				});

				vall = ($elemento.val() != '')?$elemento.val():padrao.valorPadrao;

				$elemento.val(vall).attr('rel',vall); 

				//O plugin continua aqui...

			}

		});

	}

})(jQuery);
</pre>
<p>Repare que o que vem após <em>vall =</em>(linha 25) nada mais é do que um <em>if/else</em> no modo compacto. O que vem antes da interrogação é a condição. o que vem entre os dois pontos e a interrogação é o valor retornado se a condição for verdadeira, e o que q vem depois dos dois pontos é o valor retornado se a condição for falsa. Nesse caso <em>vall</em> vai ser igual ao valor do elemento que está no HTML caso haja algum valor (<em>$element.val()</em> é diferente de vazio), e <em>vall</em> será igual ao valor passado pelo usuário ou o valor padrão do plugin, caso nenhum valor seja passado direto no HTML. Na linha 27 esse valor é passado para o elemento, e em seguida para o atributo <em>rel</em>.</p>
<p>Agora devemos criar a parte onde indicamos o que deve ocorrer quando o usuário entra ou sai do input/textarea. Primeiro vou criar a parte que indica o que deve ocorrer quando o usuário ENTRA no input/textarea.</p>
<p>Para não ficar reescrevendo todo o script, vou mostrar somente a parte onde há a interação com os elementos. Para indicar a ação de entrada no input/textarea usamos o evento <em>focus</em>, e nesta entrada executamos uma função.</p>
<pre class="brush: jscript;">
$elemento.focus(function(){

});
</pre>
<p>Quando estamos dentro do <em>focus</em> o <em>$(this)</em> indica o elemento quando está entrando em foco, então não podemos confundir com o <em>$(this)</em> usado anteriormente. Para facilitar o entendimento vou criar uma variável chamada <em>$elementoEmFoco</em> e direciona-la ao  <em>$(this)</em>.</p>
<pre class="brush: jscript;">
$elemento.focus(function(){
	$elementoEmFoco = $(this);
});
</pre>
<p>Quando entramos no input/textarea sempre haverá um valor assinalado (no tutorial em vídeo não me atentei a este detalhe, e acabei escrevendo uma parte redundante no código), e estamos seguros disto pois quando escrevermos o código para quando o cursor sair do input/textarea colocaremos um valor no mesmo. Então quando entramos queremos  ter a cor e o estilo do texto do usuário, o que é criado nas linhas 3-6</p>
<pre class="brush: jscript;">
$elemento.focus(function(){
	$elementoEmFoco = $(this);
	$elementoEmFoco.css({
		 color:padrao.corTexto
		,fontStyle:padrao.estiloTexto
	});
});
</pre>
<p>Por fim, se quando entrarmos no elemento ele tenha o valor igual ao que foi guardado no atributo <em>rel</em>, queremos que esse valor desapareça e que o input/textarea fique vazio, para que o usuário possa digitar seu texto.</p>
<pre class="brush: jscript;">
$elemento.focus(function(){
	$elementoEmFoco = $(this);
	$elementoEmFoco.css({
		 color:padrao.corTexto
		,fontStyle:padrao.estiloTexto
	});

	if($elementoEmFoco.val() == $elementoEmFoco.attr('rel')){
		$elementoEmFoco.val('');
	}

});
</pre>
<p>Terminada a ação executada quando entramos no input/textarea temos de criar a ação que será executada quando sairmos do mesmo. Para isso usamos o método <em>blur()</em>. Inicialmente faremos o mesmo que fizemos anteriormente, executaremos uma função assim que sairmos do input/textarea, e criaremos uma variável que será igual ao <em>$(this)</em>, que neste caso indica o elemento quando está saindo de foco.</p>
<pre class="brush: jscript;">
$elemento.blur(function(){
	$elementoForaDeFoco = $(this);
});
</pre>
<p>Se quando sairmos do input/textarea seu valor seja igual a vazio ou seu valor seja igual ao valor do atributo <em>rel</em>, queremos que ele seja tratado como uma marca d&#8217;água, então ele deve ter a cor e o estilo da marca d&#8217;água.</p>
<pre class="brush: jscript;">
$elemento.blur(function(){
	$elementoForaDeFoco = $(this);
	if($elementoForaDeFoco.val() == '' || $elementoForaDeFoco.val() == $elementoForaDeFoco.attr('rel')){
		$elementoForaDeFoco.css({
	 		 color     : padrao.corMarcaDagua
			,fontStyle : padrao.estiloMarcaDagua
		});
	}
});
</pre>
<p>Além disso queremos que o valor volte a ser o valor padrão do input/textarea caso o mesmo esteja vazio ou tenha o valor igual ao valor do atributo <em>rel</em>, então incluimos uma linha de código dentro do <em>if</em>.</p>
<pre class="brush: jscript;">
$elemento.blur(function(){
	$elementoForaDeFoco = $(this);
	if($elementoForaDeFoco.val() == '' || $elementoForaDeFoco.val() == $elementoForaDeFoco.attr('rel')){
		$elementoForaDeFoco.css({
	 		 color     : padrao.corMarcaDagua
			,fontStyle : padrao.estiloMarcaDagua
		});

	$elementoForaDeFoco.val($elementoForaDeFoco.attr('rel'));

	}
});
</pre>
<p>O plugin termina aqui. Farei somente uma modificação no código, que é inicializar todas as variáveis no início do documento. Esta prática não é estritamente necessária, porém particularmente eu gosto de fazer assim. A seguir está todo o plugin, incluindo essas modificações que fiz.</p>
<pre class="brush: jscript;">
(function($){

	$.fn.watermark = function(parametros){
		var  padrao
			,vall
			,$elemento
			,$elementoEmFoco
			,$elementoForaDeFoco
			,padroes = {
				 corMarcaDagua    : '#bbbbbb'
				,estiloMarcaDagua : 'italic'
				,corTexto         : '#000000'
				,estiloTexto      : 'normal'
				,valorPadrao      : 'pesquisar...'
			}

		padrao = $.extend({},padroes,parametros);

		return this.each(function(){

			$elemento = $(this);

			if($elemento.is('input:text') || $elemento.is('textarea') ){

				$elemento.css({
					 color     : padrao.corMarcaDagua
					,fontStyle: padrao.estiloMarcaDagua
				});

				vall = ($elemento.val() != '')?$elemento.val():padrao.valorPadrao;
				$elemento.val(vall).attr('rel',vall); 

				$elemento.focus(function(){
					$elementoEmFoco = $(this);
					$elementoEmFoco.css({
						 color:padrao.corTexto
						,fontStyle:padrao.estiloTexto
					});

					if($elementoEmFoco.val() == $elementoEmFoco.attr('rel')){
						$elementoEmFoco.val('');
					}

				});

				$elemento.blur(function(){
					$elementoForaDeFoco = $(this);
					if($elementoForaDeFoco.val() == '' || $elementoForaDeFoco.val() == $elementoForaDeFoco.attr('rel')){
						$elementoForaDeFoco.css({
					 		 color     : padrao.corMarcaDagua
							,fontStyle : padrao.estiloMarcaDagua
						});

					$elementoForaDeFoco.val($elementoForaDeFoco.attr('rel'));

					}
				});

			}

		});

	}

})(jQuery);
</pre>
<p>O plugin ,do jeito que está, tem 1565 bytes de tamanho, o que em princípio é considerado pequeno, porém é sempre uma boa ideia diminuir o máximo possível o tamanho dos arquivos que serão incluídos nas páginas. O próprio framework jQuery apresenta uma versão minimizada.</p>
<p>Para criar essa versão usarei um compressor chamado <em>YUI Compressor</em>. Este compressor comprimi arquivos de javascript e CSS. O primeiro passo é baixar o compressor, e para isso você deve ir à <a href="http://yuilibrary.com/downloads/#yuicompressor">página de download</a> e baixa-lo. Baixei a única versão disponível na data de criação deste tutorial 2.4.2.<br />
Primeiro você deve extrair a pasta zipada para uma pasta de sua escolha, eu escolhi a pasta que meu plugin está. Em seguida você deve jogar o plugin pra dentro da pasta <em>build</em>, que está dentro da pasta <em>yuicompressor-x.y.z</em>(no meu caso x=2, y=4 e z=2). Eu não gosto de jogar meu arquivo diretamente, eu faço uma cópia e coloco a mesma lá dentro, para evitar que, por qualquer motivo, meu arquivo seja danificado. </p>
<div class="image"><img src="http://tutorial-city.net/wp-content/uploads/2009/09/pasta.jquery.watermark.jpg" alt="pasta.jquery.watermark" title="pasta.jquery.watermark" width="683" height="181" class="aligncenter size-full wp-image-468" /></div>
<p>Para executar o compressor você deve acessar a pasta onde os arquivos estão localizados, o modo mais simples é copiando o endereço (no meu caso é o destacado na imagem acima). Agora você deve abrir o prompt de comando, caso você esteja usando Windows vá em <em>Iniciar>Executar</em>(start>Run) , digite <em>cmd</em> e pressione <em>ok</em>.</p>
<div class="image"><img src="http://tutorial-city.net/wp-content/uploads/2009/09/cmd.jquery.watermark.jpg" alt="cmd.jquery.watermark" title="cmd.jquery.watermark" width="607" height="205" class="aligncenter size-full wp-image-475" /></div>
<p>Um prompt de comando surgirá na tela. digite <em>cd &#8220;{endereço do arquivo em java e plugin}&#8221;</em>, incluindo as aspas e pressione Enter. no meu caso digitarei:</p>
<pre class="brush: java;">
cd &quot;C:\Users\Eduardo\My Documents\Aptana Studio Workspace\watermark\yuicompressor-2.4.2\build&quot;
</pre>
<p>Neste momento você deve estar na pasta onde seus arquivos estão. para criar o arquivo comprimido do plugin executamos o seguinte comando: <em>java -jar {nome do arquivo em java da pasta}.jar {nome do arquivo a ser comprimido}.js -o {nome do arquivo de saída}.js</em>. No meu caso ficou da seguinte maneira</p>
<pre class="brush: java;">
java -jar yuicompressor-2.4.2.jar jquery.watermark.js -o jquery.watermark.min.js
</pre>
<p>Em poucos instantes um arquivo é criado na pasta, chamado <em>jquery.watermark.min</em>. O tamanho dele é 679 bytes, 56,6% menor que o arquivo original. Mas tome <strong>CUIDADO</strong> para não descartar o arquivo original! Sempre que você quiser modificar seu plugin, é nele que você vai mexer, e no fim você comprimi dinovo.</p>
<p>Para testar o seu plugin crie uma página em HTML como a seguinte</p>
<pre class="brush: xml;">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
	&lt;head&gt;
		&lt;style type=&quot;text/css&quot;&gt;
			input,textarea{display:block;}
		&lt;/style&gt;
		&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot; /&gt;
		&lt;title&gt;Watermark Plugin&lt;/title&gt;
	&lt;/head&gt;
	&lt;body&gt;
		&lt;input type=&quot;text&quot; /&gt;
		&lt;input type=&quot;text&quot; value=&quot;nome&quot;/&gt;
		&lt;input type=&quot;text&quot; value=&quot;email&quot;/&gt;
		&lt;textarea rows=&quot;7&quot; cols=&quot;25&quot;&gt;Digite sua mensagem&lt;/textarea&gt;
	&lt;script type=&quot;text/javascript&quot; src=&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js&quot;&gt;&lt;/script&gt;
	&lt;script type=&quot;text/javascript&quot; src=&quot;jquery.watermark.min.js&quot;&gt;&lt;/script&gt;
	&lt;script type=&quot;text/javascript&quot;&gt;
		$(document).ready(function(){
			$('input,textarea').watermark();
		});
	&lt;/script&gt;
	&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>Não se esqueça que o arquivo minimizado deve estar na mesma página do documento em HTML para que o endereço do atributo <em>src</em>, e também não esqueça que o framework jQuery deve ser adicionado antes de todos os arquivos que contenham jQuery. Nesse caso em específico adicionei os scripts no fim da página(imediatamente antes do término do <em>body</em>), mas poderia ter sido no <em>head</em>. </p>
<p>Para executar o plugin selecionei todos os input&#8217;s e textarea&#8217;s da página (poderia selecionar somente uma parte) e executei o comando <em>watermark()</em>. Você pode modificar os valores padrões, e para isso basta escrever o objeto como parâmetro, da seguinte maneira</p>
<pre class="brush: jscript;">
$(document).ready(function(){
	$('input,textarea').watermark({
		 corMarcaDagua:'#abc'
		,estiloMarcaDagua:'normal'
		,corTexto:'green'
		,estiloTexto:'italic'
		,valorPadrao:'digite seu texto...'
	});
});
</pre>
<p>Abra a página novamente e teste. Você verá que os estilos foram mudados, além do texto marca d&#8217;água que aparece nos input&#8217;s/textarea&#8217;s que não tem valor. Você não é obrigado a passar todos os valores, mas somente aqueles que interessam ser mudados.</p>
<p>Você pode testar o resultado final, ou baixar os arquivos, nos links abaixo:</p>
<p><a href="http://tutorial-city.net/wp-content/uploads/2009/09/watermark.html">Preview Online</a><br />
<a href="http://tutorial-city.net/wp-content/uploads/2009/09/watermark.rar">Baixar Arquivos</a></p>
<img src="http://feeds.feedburner.com/~r/tutorial-city/XDvR/~4/8pt4Hl8dFJ8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tutorial-city.net/web/criando-um-plugin-de-marca-dagua-com-jquery/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		<feedburner:origLink>http://tutorial-city.net/web/criando-um-plugin-de-marca-dagua-com-jquery/</feedburner:origLink></item>
		<item>
		<title>Criando menu expansível com jQuery</title>
		<link>http://feedproxy.google.com/~r/tutorial-city/XDvR/~3/FwFwGSe3D5g/</link>
		<comments>http://tutorial-city.net/web/criando-menu-expansivel-com-jquery/#comments</comments>
		<pubDate>Mon, 07 Sep 2009 14:42:08 +0000</pubDate>
		<dc:creator>Tutorial City</dc:creator>
				<category><![CDATA[web]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[xhtml]]></category>

		<guid isPermaLink="false">http://tutorial-city.net/?p=411</guid>
		<description><![CDATA[Neste tutorial você vai aprender a criar um menu que se expande usando jQuery. swfobject.embedSWF("http://vimeo.com/moogaloop.swf","video-1","640","400","9.0.28",'',{'clip_id': 6466924,'server': 'vimeo.com','show_title': 1,'show_byline': 1,'show_portrait': 0,'color': '00ADEF','fullscreen': 1,'js_api': 1},{'bgcolor':'#ffffff','allowscriptaccess':'always','allowfullscreen':'true','scalemode':'showall','quality':'high','opaque':'wmode'}); Em primeiro lugar devemos criar a estrutura necessária para que nosso aplicativo possa viver. Para isso criei &#8230; <a href="http://tutorial-city.net/web/criando-menu-expansivel-com-jquery/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Neste tutorial você vai aprender a criar um menu que se expande usando jQuery.<span id="more-411"></span></p>
<div class="video"><script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script><script type="text/javascript">swfobject.embedSWF("http://vimeo.com/moogaloop.swf","video-1","640","400","9.0.28",'',{'clip_id': 6466924,'server': 'vimeo.com','show_title': 1,'show_byline': 1,'show_portrait': 0,'color': '00ADEF','fullscreen': 1,'js_api': 1},{'bgcolor':'#ffffff','allowscriptaccess':'always','allowfullscreen':'true','scalemode':'showall','quality':'high','opaque':'wmode'});</script>
<div id="video-1"></div>
</div>
<p>Em primeiro lugar devemos criar a estrutura necessária para que nosso aplicativo possa viver.  Para isso criei um arquivo chamado expand.html, que será responsável pela estruturação do código, um arquivo chamando expand.css, que será responsável pelo visual de uma maneira geral, e um arquivo chamado expand.js, que será responsável pelos efeitos, além da pasta com as imagens que serão usadas no menu.</p>
<div class="image">
<img src="http://tutorial-city.net/wp-content/uploads/2009/09/diretorios.jpg" alt="diretorios" title="diretorios" width="157" height="92" class="aligncenter size-full wp-image-422" />
</div>
<p>Começando pelo começo, nada é mais importante que o arquivo HTML, então vamos à ele.<br />
a estrutura básica para iniciar o projeto é vista a seguir (repare como o framework jQuery já está carregado através da tag script):</p>
<pre class="brush: xml;">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
	&lt;head&gt;
		&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot;&gt;
		&lt;title&gt;expandindo menu com jQuery&lt;/title&gt;
		&lt;script type=&quot;text/javascript&quot; src=&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js&quot;&gt;&lt;/script&gt;
	&lt;/head&gt;
	&lt;body&gt;

	&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>Em seguida precisaremos de uma lista, onde cada item representará um item do menu.<br />
dentro de cada item teremos uma imagem, um título e uma descrição.</p>
<pre class="brush: xml;">
		&lt;ul id=&quot;expand&quot;&gt;
			&lt;li&gt;
				&lt;img src=&quot;drupal.jpg&quot; alt=&quot;&quot; width=&quot;80&quot; height=&quot;80&quot; /&gt;
				&lt;h2&gt;Drupal&lt;/h2&gt;
				&lt;p&gt;Drupal is a free and open source[1] Content Management System (CMS) written in PHP. It is used as a back-end system for many different types of websites, ranging from small personal blogs to large corporate and political sites. It is distributed under the GNU GPL.&lt;/p&gt;
			&lt;/li&gt;
			&lt;li&gt;
				&lt;img src=&quot;expressionengine.jpg&quot; alt=&quot;&quot; width=&quot;80&quot; height=&quot;80&quot; /&gt;
				&lt;h2&gt;Expression Engine&lt;/h2&gt;
				&lt;p&gt;EllisLab is a software developer based in Bend, Oregon which develops applications written in PHP. The company is privately owned and has to date accepted no venture capital funding of any kind. Since the company's founding in January 2002.&lt;/p&gt;
			&lt;/li&gt;
			&lt;li&gt;
				&lt;img src=&quot;frog.jpg&quot; alt=&quot;&quot; width=&quot;80&quot; height=&quot;80&quot; /&gt;
				&lt;h2&gt;Frog CMS&lt;/h2&gt;
				&lt;p&gt;Frog CMS is an open source content management system originally developed by the company Philippe Archambault. The design decision taken from its start was to use PHP5 as the language for the software, along with a MySQL database backend, although it also has support for SQLite (version 3). It is a port of the Ruby on Rails CMS known as Radiant, although Frog has begun to take its own development direction.&lt;/p&gt;
			&lt;/li&gt;
			&lt;li&gt;
				&lt;img src=&quot;joomla.jpg&quot; alt=&quot;&quot; width=&quot;80&quot; height=&quot;80&quot; /&gt;
				&lt;h2&gt;Joomla!&lt;/h2&gt;
				&lt;p&gt;Joomla! is a content management system platform for publishing content on the World Wide Web and intranets as well as a Model-view-controller (MVC) Web Application Development framework. The system includes features such as page caching to improve performance, RSS feeds, printable versions of pages, news flashes, blogs, polls, website searching, and language internationalization. It is written in the PHP programming language and uses the MySQL database system to store information. Joomla is the result of a fork of Mambo. Released under the terms of the GNU General Public License, Joomla is free software.&lt;/p&gt;
			&lt;/li&gt;
			&lt;li&gt;
				&lt;img src=&quot;magento.jpg&quot; alt=&quot;&quot; width=&quot;80&quot; height=&quot;80&quot; /&gt;
				&lt;h2&gt;Magento&lt;/h2&gt;
				&lt;p&gt;Magento is an Open Source ecommerce web application launched on March 31, 2008. It was created by Varien, building on components of the Zend Framework. Magento is available under the Open Software License version 3.0. Since version 1.1.7 some parts are licensed under the Academic Free License version 3.0. Magento Enterprise Edition, a paid for version of Magento aimed at larger companies, was launched on April 15, 2009.&lt;/p&gt;
			&lt;/li&gt;
			&lt;li&gt;
				&lt;img src=&quot;modx.jpg&quot; alt=&quot;&quot; width=&quot;80&quot; height=&quot;80&quot; /&gt;
				&lt;h2&gt;MODx&lt;/h2&gt;
				&lt;p&gt;MODx is a free, open source content management system and web application framework for publishing content on the world wide web and intranets. MODx is licensed under the GPL. MODx is written in the PHP programming language and uses the MySQL database.&lt;/p&gt;
			&lt;/li&gt;
		&lt;/ul&gt;
</pre>
<p>Feito isso devemos estilizar nosso trabalho, então é hora de visitar o arquivo expand.css.<br />
as instruções linha a linha são a seguinte:</p>
<ol>
<li>Zerar margin e padding de todos os elementos, além das bolinhas padrão que vem nas listas</li>
<li>Dar um tamanho à div que será usada mais afrente.</li>
<li>Dar uma cor de fundo à página</li>
<li>Mostrar o menu na horizontal e dimensioná-lo, a fim de mostrar todo o conteúdo de todos os itens, além de dar um visual legal pra cada item.</li>
<li>Estilizar a imagem e flutua-la para a esquerda, assim o título e a descrição podem fluir em volta dela.</li>
<li>Estilizar a descrição. Repare que a propriedade margin-left é igual à distância do texto à extrema esquerda de seu pai, e isso serve para que o mesmo não flua para baixo da imagem.</li>
<li>Estilizar o título.</li>
<li>Dar background rosa aos itens pares da lista.</li>
<li>Dar background verde aos itens impares da leta.</li>
</ol>
<pre class="brush: css;">
*{
    margin:0;
    padding:0;
    list-style:none;
}

div{
    overflow:hidden;
    width:450px;
}

html{
    background:#ccc;
}

#expand li{
    float:left;
    width:390px;
    height:170px;
    margin:2px;
    overflow:hidden;
    border:1px solid #555;
    -moz-border-radius:10px;
    -webkit-border-radius:10px;
}

#expand img{
    border:3px solid #686;
    background: #aaa;
    padding:3px;
    float:left;
    margin:3px 5px;
}

#expand p{
    font:normal normal normal 11px/1.4 arial,sans-serif;
    float:none;
    padding:3px 12px 0 5px;
    margin:5px 0 0 102px;
}

#expand h2{
    font:bold italic normal 15px/1 georgia,serif;
    margin:3px 0 0 108px;
}

#expand li:nth-child(even){
    background: #dff;
}

#expand li:nth-child(odd){
    background: #fdf;
}
</pre>
<p>Repare que as duas últimas linhas são formadas por propriedades presentes somente em CSS3, mas são reconhecidas em todos os navegadores modernos (ou seja, Firefox, Safari, Chrome e Opera). Por último devemos criar o efeito usando jQuery. Abrindo arquivo expand.js, o primeiro que devemos fazer é iniciar o jQuery.</p>
<pre class="brush: jscript;">
$(document).ready(function(){

});
</pre>
<p>O segundo passo é criar uma div que vai envolver todo o conteúdo dos itens.  Esta parte é importante para que o texto não flua quando o item expandir e retrair.</p>
<pre class="brush: jscript;">
$('#expand li').wrapInner('&lt;div&gt;');
</pre>
<p>Em seguida usamos jQuery para diminuir todos os itens, e mostrar somente a imagem.</p>
<pre class="brush: jscript;">
$('#expand li').css({
		 width:  '102px'
		,height: '100px'
	});
</pre>
<p>Cada item tem uma altura diferente, e para podermos expandir uma altura suficiente para mostrar todo o conteúdo devemos primeiro conhecer a altura do maior deles, então um loop é criado para rodar todos as divs e pegar a maior altura encontrada</p>
<pre class="brush: jscript;">
	var alturaMax = 100;

	$('#expand li div').each(function(){
		alturaDiv = $(this).height();
		if(alturaDiv &gt; alturaMax){
			alturaMax = alturaDiv;
		}
	});
</pre>
<p>A seguir vem a animação em si</p>
<pre class="brush: jscript;">
$('#expand li').hover(/*mouse em cima*/,/*mouse saindo*/);
</pre>
<p>Quando o mouse estiver em cima, queremos expandir o item para 450px de largura e para a altura do maior dos itens, mas somente depois de parar o que estava fazendo.</p>
<pre class="brush: jscript;">
$('#expand li').hover(function(){
		$(this).stop().animate({
			 width:  '450px'
			,height: alturaMax + 5 + 'px'
		});
	},/*mouse saindo*/);
</pre>
<p>Quando o mouse deixa o item, queremos que o mesmo pare o que estiver fazendo e volte a animar retornando à posição inicial</p>
<pre class="brush: jscript;">
$('#expand li').hover(function(){
		$(this).stop().animate({
			 width:  '450px'
			,height: alturaMax + 5 + 'px'
		});
	},function(){
		$(this).stop().animate({
			 width:  '102px'
			,height: '100px'
		});
	});
</pre>
<p>Nesse ponto o script já funciona e faz exatamente o que queremos, mas bons programadores sempre retornam ao seu código e tentam o tornar melhor. O arquivo criado, apesar de funcionar, apresentam um monte de más práticas quando se diz respeito a javascript, e a seguir tentaremos contornar esses problemas.</p>
<p>A primeira parte que devemos notar é que o seguinte fragmento do código é chamada inúmeras vezes</p>
<pre class="brush: jscript;">
$('#expand li')
</pre>
<p>Chamadas por elementos do DOM são demasiadamente penosas em javascript, e como fazemos estas chamadas várias vezes usando jQuery, nosso script acaba se tornando bastante lento. Para solucionar este problema devemos armazenar todos as chamadas em cache, mas só faz sentido fazer isso caso esta chamada seja feita mais de uma vez. O mesmo deve ser feito com a variável $(this), porém nesse caso elas são chamadas somente uma vez em cada loop, então não se deve tocar nelas. Corrigindo este problema, nosso código fica da seguinte maneira</p>
<pre class="brush: jscript;">
$(document).ready(function(){

	var $item = $('#expand li');

	$item.wrapInner('&lt;div&gt;');

	$item.css({
		 width:  '102px'
		,height: '100px'
	});

	var alturaMax = 100;

	$item.children('div').each(function(){
		alturaDiv = $(this).height();
		if(alturaDiv &gt; alturaMax){
			alturaMax = alturaDiv;
		}
	});

	$item.hover(function(){
		$(this).stop().animate({
			 width:  '450px'
			,height: alturaMax + 5 + 'px'
		});
	},function(){
		$(this).stop().animate({
			 width:  '102px'
			,height: '100px'
		});
	});
});
</pre>
<p>Um passo adicional que podemos tomar é usar o que é conhecido em javascript como <em>chaining</em>. Isto significa aplicar seguidas funções sem sair de um contexto. Talvez fique mais claro no código abaixo</p>
<pre class="brush: jscript;">
$(document).ready(function(){

	var $item = $('#expand li');
	var alturaMax = 100;

	$item.wrapInner('&lt;div&gt;')
		 .css({
		 width:  '102px'
		,height: '100px'
	  })//não se usa ';' aqui, para que os métodos possam ser acorrentados
	  	.children('div').each(function(){
		alturaDiv = $(this).height();
		if(alturaDiv &gt; alturaMax){
			alturaMax = alturaDiv;
		}
	 })//não se usa ';' aqui, para que os métodos possam ser acorrentados
		.hover(function(){
		$(this).stop().animate({
			 width:  '450px'
			,height: alturaMax + 5 + 'px'
		});
	},function(){
		$(this).stop().animate({
			 width:  '102px'
			,height: '100px'
		});
	});
});
</pre>
<p>Neste momento o script já está bem mais rápido, e agora podemos criar mais um efeito onde a altura do item será animado o suficiente para mostrar todo o seu conteúdo, então se o item tiver pouco conteúdo a sua altura expandirá pouco ou não expandirá, e caso o item tenha bastante conteúdo a sua altura expandirá o necessário para que mostre todo o texto.</p>
<p>Para este efeito devemos descobrir a altura da div quando passamos o mouse por cima do item (repare que comentei o código que não será mais usado e modifiquei a variável que dá a altura do item da lista) .</p>
<pre class="brush: jscript;">
$(document).ready(function(){

	var $item = $('#expand li');
	var alturaMax = 100,altura;

	$item.wrapInner('&lt;div&gt;')
		 .css({
		 width:  '102px'
		,height: '100px'
	  })//não se usa ';' aqui, para que os métodos possam ser acorrentados
//	  	.children('div').each(function(){
//		alturaDiv = $(this).height();
//		if(alturaDiv &gt; alturaMax){
//			alturaMax = alturaDiv;
//		}
//	 })
		.hover(function(){
		altura = $(this).children('div').height();
		$(this).stop().animate({
			 width:  '450px'
			,height: altura + 5 + 'px'
		});
	},function(){
		$(this).stop().animate({
			 width:  '102px'
			,height: '100px'
		});
	});
});
</pre>
<p>Abaixo está o conteúdo de todos os arquivos criados.</p>
<h3>xHTML</h3>
<pre class="brush: xml;">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
	&lt;head&gt;
		&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=iso-8859-1&quot; /&gt;
		&lt;title&gt;sem título&lt;/title&gt;
		&lt;link type=&quot;text/css&quot; href=&quot;expand.css&quot; rel=&quot;stylesheet&quot;/&gt;
		&lt;script type=&quot;text/javascript&quot; src=&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js&quot;&gt;&lt;/script&gt;
		&lt;script type=&quot;text/javascript&quot; src=&quot;expand.js&quot;&gt;&lt;/script&gt;
	&lt;/head&gt;
	&lt;body&gt;
		&lt;ul id=&quot;expand&quot;&gt;
			&lt;li&gt;
				&lt;img src=&quot;imagens/drupal.jpg&quot; alt=&quot;&quot; width=&quot;80&quot; height=&quot;80&quot; /&gt;
				&lt;h2&gt;Drupal&lt;/h2&gt;
				&lt;p&gt;Drupal is a free and open source[1] Content Management System (CMS) written in PHP. It is used as a back-end system for many different types of websites, ranging from small personal blogs to large corporate and political sites. It is distributed under the GNU GPL.&lt;/p&gt;
			&lt;/li&gt;
			&lt;li&gt;
				&lt;img src=&quot;imagens/expressionengine.jpg&quot; alt=&quot;&quot; width=&quot;80&quot; height=&quot;80&quot; /&gt;
				&lt;h2&gt;Expression Engine&lt;/h2&gt;
				&lt;p&gt;EllisLab is a software developer based in Bend, Oregon which develops applications written in PHP. The company is privately owned and has to date accepted no venture capital funding of any kind. Since the company's founding in January 2002.&lt;/p&gt;
			&lt;/li&gt;
			&lt;li&gt;
				&lt;img src=&quot;imagens/frog.jpg&quot; alt=&quot;&quot; width=&quot;80&quot; height=&quot;80&quot; /&gt;
				&lt;h2&gt;Frog CMS&lt;/h2&gt;
				&lt;p&gt;Frog CMS is an open source content management system originally developed by the company Philippe Archambault. The design decision taken from its start was to use PHP5 as the language for the software, along with a MySQL database backend, although it also has support for SQLite (version 3). It is a port of the Ruby on Rails CMS known as Radiant, although Frog has begun to take its own development direction.&lt;/p&gt;
			&lt;/li&gt;
			&lt;li&gt;
				&lt;img src=&quot;imagens/joomla.jpg&quot; alt=&quot;&quot; width=&quot;80&quot; height=&quot;80&quot; /&gt;
				&lt;h2&gt;Joomla!&lt;/h2&gt;
				&lt;p&gt;Joomla! is a content management system platform for publishing content on the World Wide Web and intranets as well as a Model-view-controller (MVC) Web Application Development framework. The system includes features such as page caching to improve performance, RSS feeds, printable versions of pages, news flashes, blogs, polls, website searching, and language internationalization. It is written in the PHP programming language and uses the MySQL database system to store information. Joomla is the result of a fork of Mambo. Released under the terms of the GNU General Public License, Joomla is free software.&lt;/p&gt;
			&lt;/li&gt;
			&lt;li&gt;
				&lt;img src=&quot;imagens/magento.jpg&quot; alt=&quot;&quot; width=&quot;80&quot; height=&quot;80&quot; /&gt;
				&lt;h2&gt;Magento&lt;/h2&gt;
				&lt;p&gt;Magento is an Open Source ecommerce web application launched on March 31, 2008. It was created by Varien, building on components of the Zend Framework. Magento is available under the Open Software License version 3.0. Since version 1.1.7 some parts are licensed under the Academic Free License version 3.0. Magento Enterprise Edition, a paid for version of Magento aimed at larger companies, was launched on April 15, 2009.&lt;/p&gt;
			&lt;/li&gt;
			&lt;li&gt;
				&lt;img src=&quot;imagens/modx.jpg&quot; alt=&quot;&quot; width=&quot;80&quot; height=&quot;80&quot; /&gt;
				&lt;h2&gt;MODx&lt;/h2&gt;
				&lt;p&gt;MODx is a free, open source content management system and web application framework for publishing content on the world wide web and intranets.&lt;/p&gt;
			&lt;/li&gt;
		&lt;/ul&gt;
	&lt;/body&gt;
&lt;/html&gt;
</pre>
<h3>CSS</h3>
<pre class="brush: css;">
*{
    margin:0;
    padding:0;
    list-style:none;
}

div{
    overflow:hidden;
    width:450px;
}

html{
     background:#ccc;
}

#expand li{
    float:left;
    width:390px;
    height:220px;
    margin:2px;
    overflow:hidden;
    border:1px solid #555;
    -moz-border-radius:10px;
    -webkit-border-radius:10px;
}
#expand img{
    border:3px solid #686;
    background: #aaa;
    padding:3px;
    float:left;
    margin:3px 5px;
}

#expand p{
    font: normal normal normal 11px/1.4 arial,sans-serif;
    padding:3px 12px 0 5px;
    margin:5px 0 0 102px;
}

#expand h2{
    font:bold italic normal 15px/1 georgia,serif;
    margin:3px 0 0 108px;
}

#expand li:nth-child(even){
    background: #dff;
}

#expand li:nth-child(odd){
    background: #fdf;
}
</pre>
<h3>jQuery</h3>
<pre class="brush: jscript;">
/**
 * @author http://tutorial-city.net/
 */

$(document).ready(function(){

	var $item = $('#expand li');
	var alturaMax = 100;

	$item.wrapInner('&lt;div&gt;')
		 .css({
		 width:  '102px'
		,height: '100px'
	  })
	  	.hover(function(){
		altura = $(this).children('div').height();
		$(this).stop().animate({
			 width:  '450px'
			,height: altura + 5 + 'px'
		});
	},function(){
		$(this).stop().animate({
			 width:  '102px'
			,height: '100px'
		});
	});
});
</pre>
<p>Espero que tenha aprendido bastante com este tutorial, e sinta-se à vontade para comentar e acrescentar ao que foi passado. Abraços e até a próxima!</p>
<img src="http://feeds.feedburner.com/~r/tutorial-city/XDvR/~4/FwFwGSe3D5g" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tutorial-city.net/web/criando-menu-expansivel-com-jquery/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
		<feedburner:origLink>http://tutorial-city.net/web/criando-menu-expansivel-com-jquery/</feedburner:origLink></item>
		<item>
		<title>Como passar um layout do Photoshop para xHTML/CSS (parte 3)</title>
		<link>http://feedproxy.google.com/~r/tutorial-city/XDvR/~3/AdUT14GwXC8/</link>
		<comments>http://tutorial-city.net/web/como-passar-um-layout-do-photoshop-para-xhtmlcss-parte-3/#comments</comments>
		<pubDate>Sat, 22 Aug 2009 14:58:55 +0000</pubDate>
		<dc:creator>Tutorial City</dc:creator>
				<category><![CDATA[web]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[desenvolvimento]]></category>
		<category><![CDATA[tableless]]></category>
		<category><![CDATA[xhtml]]></category>

		<guid isPermaLink="false">http://tutorial-city.net/?p=405</guid>
		<description><![CDATA[Nesta terceira, e última, parte mostro como corrigir os bugs do internet explorer, para que o site possa ser visto &#8220;igualmente&#8221; em todos os navegadores. Felizmente dentro de alguns anos esse processo não será mais necessário, mas enquanto isso não &#8230; <a href="http://tutorial-city.net/web/como-passar-um-layout-do-photoshop-para-xhtmlcss-parte-3/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Nesta terceira, e última, parte mostro como corrigir os bugs do internet explorer, para que o site possa ser visto &#8220;igualmente&#8221; em todos os navegadores. Felizmente dentro de alguns anos esse processo não será mais necessário, mas enquanto isso não acontece nós ainda devemos compensar para os navegadores mais antigos e fora dos padrões.<span id="more-405"></span></p>
<div class="video"><script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script><script type="text/javascript">swfobject.embedSWF("http://vimeo.com/moogaloop.swf","video-1","640","400","9.0.28",'',{'clip_id': 6221048,'server': 'vimeo.com','show_title': 1,'show_byline': 1,'show_portrait': 0,'color': '00ADEF','fullscreen': 1,'js_api': 1},{'bgcolor':'#ffffff','allowscriptaccess':'always','allowfullscreen':'true','scalemode':'showall','quality':'high','opaque':'wmode'});</script>
<div id="video-1"></div>
</div>
<img src="http://feeds.feedburner.com/~r/tutorial-city/XDvR/~4/AdUT14GwXC8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tutorial-city.net/web/como-passar-um-layout-do-photoshop-para-xhtmlcss-parte-3/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		<feedburner:origLink>http://tutorial-city.net/web/como-passar-um-layout-do-photoshop-para-xhtmlcss-parte-3/</feedburner:origLink></item>
		<item>
		<title>Como passar um layout do Photoshop para xHTML/CSS (parte 2)</title>
		<link>http://feedproxy.google.com/~r/tutorial-city/XDvR/~3/KTS9ZYbsc_A/</link>
		<comments>http://tutorial-city.net/web/como-passar-um-layout-do-photoshop-para-xhtml-css-parte-2/#comments</comments>
		<pubDate>Sat, 15 Aug 2009 12:06:30 +0000</pubDate>
		<dc:creator>Tutorial City</dc:creator>
				<category><![CDATA[web]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[desenvolvimento]]></category>
		<category><![CDATA[tableless]]></category>
		<category><![CDATA[xhtml]]></category>

		<guid isPermaLink="false">http://tutorial-city.net/?p=356</guid>
		<description><![CDATA[Nesta parte faço todo o design com CSS, e como bônus ainda mostro algumas técnicas no Photoshop e no Firefox sobre como agilizar o trabalho. Na parte três farei o layout ficar compatível com o falecido internet explorer 6(e também &#8230; <a href="http://tutorial-city.net/web/como-passar-um-layout-do-photoshop-para-xhtml-css-parte-2/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Nesta parte faço todo o design com CSS, e como bônus ainda mostro algumas técnicas no Photoshop e no Firefox sobre como agilizar o trabalho.<span id="more-356"></span><br />
Na parte três farei o layout ficar compatível com o falecido internet explorer 6(e também a versão 7 e 8).</p>
<h3>Como passar um layout do Photoshop para xHTML/CSS (parte 2)</h3>
<div class="video"><script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script><script type="text/javascript">swfobject.embedSWF("http://vimeo.com/moogaloop.swf","video-1","640","400","9.0.28",'',{'clip_id': 6112721,'server': 'vimeo.com','show_title': 1,'show_byline': 1,'show_portrait': 0,'color': '00ADEF','fullscreen': 1,'js_api': 1},{'bgcolor':'#ffffff','allowscriptaccess':'always','allowfullscreen':'true','scalemode':'showall','quality':'high','opaque':'wmode'});</script>
<div id="video-1"></div>
</div>
<img src="http://feeds.feedburner.com/~r/tutorial-city/XDvR/~4/KTS9ZYbsc_A" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tutorial-city.net/web/como-passar-um-layout-do-photoshop-para-xhtml-css-parte-2/feed/</wfw:commentRss>
		<slash:comments>29</slash:comments>
		<feedburner:origLink>http://tutorial-city.net/web/como-passar-um-layout-do-photoshop-para-xhtml-css-parte-2/</feedburner:origLink></item>
		<item>
		<title>Como passar um layout do Photoshop para xHTML/CSS (parte 1)</title>
		<link>http://feedproxy.google.com/~r/tutorial-city/XDvR/~3/UKoV6VdiXn8/</link>
		<comments>http://tutorial-city.net/web/como-passar-um-layout-do-photoshop-para-xhtml-css-parte-1/#comments</comments>
		<pubDate>Sun, 28 Jun 2009 20:02:30 +0000</pubDate>
		<dc:creator>Tutorial City</dc:creator>
				<category><![CDATA[web]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[desenvolvimento]]></category>
		<category><![CDATA[tableless]]></category>
		<category><![CDATA[xhtml]]></category>

		<guid isPermaLink="false">http://tutorial-city.net/?p=333</guid>
		<description><![CDATA[Neste tutorial você os detalhes de como transformar um layout do photoshop (ou qualquer outro programa) para xHTML válido, seguindo os padrões mais atuais da web. Nesta primeira parte abordo somente a parte de xHTML, já na segunda pretendo abordar &#8230; <a href="http://tutorial-city.net/web/como-passar-um-layout-do-photoshop-para-xhtml-css-parte-1/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Neste tutorial você os detalhes de como transformar um layout do photoshop (ou qualquer outro programa) para xHTML válido, seguindo os padrões mais atuais da web.<span id="more-333"></span> Nesta primeira parte abordo somente a parte de xHTML, já na segunda pretendo abordar os detalhes de como fatirar o layout e usar CSS para deixar o visual o mais parecido possível com o proposto.</p>
<h3>Como passar um layout do Photoshop para xHTML/CSS (parte 1)</h3>
<p>
<div id="video-1"></div>
</p>
<p><script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script><br />
<script type="text/javascript">swfobject.embedSWF("http://vimeo.com/moogaloop.swf","video-1","640","400","9.0.28",'',{'clip_id': 5482921,'server': 'vimeo.com','show_title': 1,'show_byline': 1,'show_portrait': 0,'color': '00ADEF','fullscreen': 1,'js_api': 1},{'bgcolor':'#ffffff','allowscriptaccess':'always','allowfullscreen':'true','scalemode':'showall','quality':'high','opaque':'wmode'});</script></p>
<img src="http://feeds.feedburner.com/~r/tutorial-city/XDvR/~4/UKoV6VdiXn8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tutorial-city.net/web/como-passar-um-layout-do-photoshop-para-xhtml-css-parte-1/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		<feedburner:origLink>http://tutorial-city.net/web/como-passar-um-layout-do-photoshop-para-xhtml-css-parte-1/</feedburner:origLink></item>
	<media:rating>nonadult</media:rating></channel>
</rss>
