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

<channel>
	<title>Profissionais TI - Pra quem respira informação &#187; Desenvolvimento Web</title>
	<atom:link href="http://www.profissionaisti.com.br/tag/desenvolvimento-web/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.profissionaisti.com.br</link>
	<description>Pra quem respira informação</description>
	<lastBuildDate>Sun, 12 Feb 2012 12:27:26 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Primeiros passos no desenvolvimento com o web2py &#8211; Tutorial parte 1</title>
		<link>http://www.profissionaisti.com.br/2010/06/primeiros-passos-no-desenvolvimento-com-o-web2py-tutorial-parte-1/</link>
		<comments>http://www.profissionaisti.com.br/2010/06/primeiros-passos-no-desenvolvimento-com-o-web2py-tutorial-parte-1/#comments</comments>
		<pubDate>Mon, 14 Jun 2010 16:37:54 +0000</pubDate>
		<dc:creator>Bruno Rocha</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Agile]]></category>
		<category><![CDATA[Desenvolvimento Web]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.profissionaisti.com.br/?p=11244</guid>
		<description><![CDATA[Web2py é um framework livre de código aberto, utilizado para o desenvolvimento ágil de aplicações web seguras, baseadas em banco de dados; foi desenvolvido em Python e é programável com Python. Trata-se de um framework “full-stacked”, ou seja, ele já vem com todos os componentes necessários para o desenvolvimento básico de aplicações para web. As [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><img class="alignnone" title="web2py-logo" src="http://www.web2py.com/examples/static/web2py_logo.png" alt="logo" width="327" height="105" /></p>
<blockquote><p>Web2py é um framework livre de código aberto, utilizado para o desenvolvimento ágil de aplicações web seguras,<br />
baseadas em banco de dados; foi desenvolvido em Python e é programável com Python.<br />
Trata-se de um framework “full-stacked”, ou seja, ele já vem com todos os componentes necessários para o desenvolvimento básico de aplicações para web.<br />
As aplicações no web2py são desenvolvidas seguindo o padrão MVC, que permite a melhor organização entre as camadas de dados, lógica e apresentação.<br />
Além de diversos facilitadores para as tarefas de modelagem de banco de dados, criação de formulários com validação e Ajax, marcação de templates e upload de arquivos, o web2py também possui uma estrutura pronta para servir conteúdo nos mais diversos formatos, como por exemplo feeds RSS, webservices XML-RPC e permite a utilização de módulos e plugins adicionais.<br />
O web2py possibilita que o desenvolvedor dedique-se integralmente à criação da aplicação, pois não demanda instalações nem configurações complicadas: basta baixar o framework e começar a desenvolver.</p></blockquote>
<p><span style="font-family: Consolas, Monaco, 'Courier New', Courier, monospace; font-size: small;"><span style="line-height: 18px; white-space: pre;"><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: small;"><span style="line-height: 19px; white-space: normal;">Uma das principais características do web2py é o fato de não demandar instalação para o início do desenvolvimento: basta baixar o binário executável, que já vem, inclusive, com o interpretador Python, banco de dados e o WebServer. Caso seu sistema operacional já tenha o Python 2.5+ instalado, você pode baixar o fonte do web2py e executar.</span></span></span></span></p>
<p><span style="font-size: small;"><span style="color: #0000ff;">Apesar de você ter a possibilidade de desenvolver utilizando seu IDE ou editor favorito, o web2py vem com uma interface administrativa bastante completa, que permite administrar bases de dados, gerenciar aplicações e editar códigos em um editor web-based. O web2py já vem com o plugin do </span><a href="http://code.google.com/p/zen-coding/" target="_blank"><span style="color: #0000ff;">Zen-Coding</span></a><span style="color: #0000ff;"> habilitado.</span></span></p>
<p><a href="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-08-at-20.54.50.jpg" target="_blank"><img class="alignnone size-medium wp-image-50" title="web2pyEditor" src="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-08-at-20.54.50-300x232.jpg" alt="" width="300" height="232" /></a></p>
<p><span style="font-size: x-small;"><span style="font-size: small;">O web2py utiliza o padrão de MVC, que possibilita uma separação inteligente entre o modelo de dados (Model), a lógica da aplicação (Controller) e a interface de apresentação (View). Este padrão permite que o programador desenvolva os Models e Controllers, e que um designer trabalhe com as Views de uma forma muito intuitiva, com liberdade de criação do HTML. Porém, o web2py tem um modelo próprio de marcação de template que dá a liberdade de, em alguns casos, executar o código Python mais complexo diretamente na VIEW, sendo assim um framework bastante dinâmico. </span></span></p>
<blockquote><p><span style="font-size: x-small;"><span style="font-size: small;">De acordo com o seu criador, o web2py foi inspirado no Ruby on Rails, por permitir o desenvolvimento ágil. Também foi inspirado no Django, no sentido de fornecer facilitadores, geradores de formulários e camada de abstração do acesso a dados.</span></span></p></blockquote>
<p><span style="font-size: small;">Antes de começar o tutorial, que irá mostrar <strong>como desenvolver um blog com administração de posts e inserção de comentários com pesquisa via Ajax</strong>, vou listar as principais características do framework.</span></p>
<ul>
<li><span style="font-size: small;">Livre, OpenSource</span></li>
<li><span style="font-size: small;">Mecanismos de segurança em formulários</span></li>
<li><span style="font-size: small;">Autenticação integrada RBAC</span></li>
<li><span style="font-size: small;">Garantia de compatibilidade entre versões</span></li>
<li><span style="font-size: small;">Fácil de executar, não necessitando instalação, permitindo executar e armazenar projetos em um pen-drive</span></li>
<li><span style="font-size: small;">Não necessita de configuração inicial (mas possibilita configuração refinada, caso seja necessário)</span></li>
<li><span style="font-size: small;">MVC &#8211; Model &#8211; View &#8211; Controller</span></li>
<li><span style="font-size: small;">Roda em Mac, Unix, Linux, Windows, Google App Engine, Amazon EC2, e quase todos os webservers através do Python ou via Java com o Jython</span></li>
<li><span style="font-size: small;">Roda no Apache e em qualquer webserver com CGI, fastCGI, WSGI, mod_proxy ou mod_python</span></li>
<li><span style="font-size: small;">Conversa com a maioria dos bancos SQL, incluindo SQlite, PostGre, MySQL, MSSQL ORACLE, entre outros</span></li>
<li><span style="font-size: small;">Muitas maneiras de servir informações como HTML/XML, ATOM, RSS, RTF, JSON, AJAX, XML-RPC, REST, RDF</span></li>
<li><span style="font-size: small;">Permite distribuir as aplicações compiladas</span></li>
<li><span style="font-size: small;">Sistema facilitado para internacionalização, permitindo múltiplas línguas em uma única aplicação</span></li>
</ul>
<p>Agora vamos ao que interessa! Na <a href="http://rochacbruno.com.br/blog/2010/06/desenvolvimento-com-web2py-tutorial-pt1/2/" target="_blank">próxima página</a>, daremos início ao tutorial.</p>
<p><span style="font-size: x-small;"><span style="font-size: small;"><strong>TUTORIAL &#8211; Construindo um blog com banco de dados, administração de posts, comentários, imagens e documentos anexos, RSS e busca via Ajax &#8211; Parte 1</strong></span></span></p>
<p><span style="font-size: x-small;"><span style="font-size: small;">1. Faça o download do web2py</span></span></p>
<p><span style="font-size: x-small;"><span style="font-size: small;">Isso depende do seu sistema operacional e também do fato de você ter ou não o Python instalado. Eu aconselho você a instalar o Python 2.5+ no seu sistema operacional e baixar a versão de código fonte, mas você pode pular este passo e baixar um executável caso esteja usando Mac ou Windows:</span></span></p>
<p><span style="font-size: x-small;"><span style="font-size: small;"><a href="http://www.web2py.com/examples/static/web2py_win.zip" target="_blank">Baixe aqui o executável completo para windows</a></span></span></p>
<p><span style="font-size: x-small;"><span style="font-size: small;"><a href="http://www.web2py.com/examples/static/web2py_osx.zip" target="_blank">Baixe aqui o executável completo para Mac</a></span></span></p>
<p><span style="font-size: x-small;"><span style="font-size: small;">Caso prefira usar a versão código-fonte:</span></span></p>
<p><span style="font-size: x-small;"><span style="font-size: small;"><a href="http://python.org" target="_blank">Baixe e instale o Python caso ainda não tenha</a></span></span></p>
<p><span style="font-size: x-small;"><span style="font-size: small;"><a href="http://www.web2py.com/examples/static/web2py_src.zip" target="_blank">Baixe aqui o web2py source-code</a></span></span></p>
<p>2. Executando o web2py</p>
<p>Caso tenha baixado as versões executáveis, apenas descompacte e execute no Mac ou Windows.<br />
Já no caso da versão source code, após ter instalado o Python abra um terminal do seu sistema operacional e digite:</p>
<pre class="brush:shell"> python web2py.py</pre>
<p><span style="font-size: small;">Ao executar, o web2py exibirá uma tela com algumas configurações iniciais:</span></p>
<p><span style="font-size: small;"><a href="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-08-at-21.27.20.jpg"><img class="alignnone size-medium wp-image-51" title="Screen shot 2010-06-08 at 21.27.20" src="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-08-at-21.27.20-300x234.jpg" alt="" width="300" height="234" /></a></span></p>
<p><span style="font-size: small;"><strong>Choose a password: </strong> neste campo coloque uma senha qualquer, ela será exigida para que você possa acessar o admin do web2py.<br />
<strong> Running from host</strong>: não altere este campo, ele é a porta de loopback que indica que o webserver está rodando na sua própria máquina.<br />
<strong> Running from port:</strong> deixe como está e ele rodará na porta 8000, mude apenas se quiser publicar o conteúdo na porta 80 ou se a porta 800 já estiver ocupada; para desenvolvimento não é necessário alterar.</span></p>
<p><span style="font-size: small;">Após clicar em <strong><em>Start Server</em></strong>, você terá o <strong>web2py</strong> rodando e o seu navegador abrirá automaticamente a aplicação de boas vindas. Caso isso não aconteça, abra seu navegador (eu disse navegador não I.E) e vá para o seguinte endereço:</span></p>
<p><span style="font-size: small;"><a href="http://127.0.0.1:8000" target="_blank">http://127.0.0.1:8000</a></span></p>
<p><span style="font-size: small;">Você verá a tela de boas vindas, o que significa que já está tudo rodando e que podemos iniciar o desenvolvimento.</span></p>
<p><span style="font-size: small;"><a href="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-08-at-21.35.08.jpg"><img class="alignnone size-medium wp-image-52" title="Screen shot 2010-06-08 at 21.35.08" src="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-08-at-21.35.08-300x110.jpg" alt="" width="300" height="110" /></a></span></p>
<p><span style="font-size: small;">Clique no link <strong>[click here for administrative interface]</strong>, será necessário colocar a senha configurada no início&#8230;</span></p>
<p><a href="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-08-at-21.37.40.jpg"><img class="alignnone size-medium wp-image-53" title="Screen shot 2010-06-08 at 21.37.40" src="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-08-at-21.37.40-300x143.jpg" alt="" width="300" height="143" /></a></p>
<p><span style="font-size: small;">&#8230; e então você terá acesso ao <strong>Admin</strong> do web2py (clique na imagem abaixo para ampliar)</span></p>
<p><span style="font-size: small;"><a href="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-08-at-21.39.14.jpg"><img class="alignnone size-medium wp-image-54" title="Screen shot 2010-06-08 at 21.39.14" src="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-08-at-21.39.14-300x165.jpg" alt="" width="300" height="165" /></a></span></p>
<p><span style="font-size: small;">Nesta tela de administração, é possível acessar os seguintes itens:</span></p>
<ol>
<li> Lista de aplicações instaladas</li>
<li>Informações sobre versão e link para atualização automática do web2py</li>
<li>Formulário para criação de novas aplicações</li>
<li>Formulário para importação de aplicação empacotada</li>
<li>Últimos anúncios oficiais via Twitter do web2py</li>
</ol>
<p><span style="font-size: small;">As aplicações instaladas são pastas que estão dentro da pasta APPLICATIONS do framework, por isso, você pode utilizar seu editor ou IDE favorita e chamar via terminal algumas funções específicas do core do web2py. Porém, neste tutorial, iremos abordar apenas o trabalho efetuado diretamente na interface web &#8211; assim, todo o trabalho será feito no navegador.</span></p>
<p><span style="font-size: small;">Para começar, crie uma nova aplicação chamada <strong>BLOG </strong></span></p>
<p><span style="font-size: small;"><a href="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-08-at-21.55.23.jpg"><img class="alignnone size-full wp-image-55" title="Screen shot 2010-06-08 at 21.55.23" src="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-08-at-21.55.23.jpg" alt="" width="516" height="211" /></a></span></p>
<p><span style="font-size: small;">Insira o nome <strong>BLOG</strong> e clique em <strong>Create.</strong></span></p>
<p><span style="font-size: small;">Você será redirecionado para a página de DESIGN da sua aplicação </span></p>
<p><span style="font-size: small;"><a href="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-08-at-21.57.19.jpg"><img class="alignnone size-medium wp-image-56" title="Screen shot 2010-06-08 at 21.57.19" src="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-08-at-21.57.19-300x63.jpg" alt="" width="300" height="63" /></a></span></p>
<p><span style="font-size: small;">Nesta página, 3 seções distintas são apresentadas:</span></p>
<p><span style="font-size: small;"><strong>MODELS, CONTROLLERS, VIEWS</strong></span></p>
<p><span style="font-size: small;">Em cada uma dessas seções iremos desenvolver o código da aplicação. Mais abaixo, você verá outras opções como a <strong>LANGUAGES</strong>, que permite a definição das linguagens da app;  <strong>STATIC FILES</strong>, que contém arquivos estáticos que não exigem processamento (como imagens, arquivos de upload etc); <strong>MODULES</strong>, que é usado para armazenar módulos Python externos; e <strong>PLUGINS,</strong> que permite adicionar uma série de plugins para paginação, grids, interfaces, entre outras coisas.</span></p>
<p><span style="font-size: small;">Vamos começar pelo <strong>MODEL</strong>. Procure a linha que indica o arquivo <strong>db.py</strong> e clique em <strong>edit</strong></span></p>
<p><span style="font-size: small;"><a href="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-08-at-22.13.58.jpg"><img class="alignnone size-full wp-image-57" title="Screen shot 2010-06-08 at 22.13.58" src="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-08-at-22.13.58.jpg" alt="" width="444" height="122" /></a></span></p>
<p><span style="font-size: small;">Por padrão, este arquivo inicialmente se chama db.py, mas poderia ter qualquer outro nome. Neste arquivo iremos definir o banco de dados e o modelo das tabelas. Como o web2py já vem nativamente com o SQLite (na verdade já vem no Python), usaremos o SQLite, mas seria o mesmo processo para qualquer outro banco suportado, necessitando apenas a alteração da string de conexão.</span></p>
<p><span style="font-size: small;">A String de Conexão</span></p>
<p><span style="font-size: small;">Ignore os comentários e todo o restante do código que está no arquivo db.py. Deixe-o como está e procure a linha:</span></p>
<pre class="brush:py">db = DAL('sqlite://storage.sqlite')</pre>
<p><span style="font-size: small;"><br />
Na linha acima definimos uma variável &#8220;db&#8221; que será nossa referência para o banco sqlite (armazenado na pasta databases do framework com o nome storage.sqlite). Este nome é um padrão, </span><span style="font-size: small;">mas poderíamos mudar o nome do banco na string de conexão, de acordo com o tipo de banco de dados.<br />
</span></p>
<p><span style="font-size: small;">O web2py tem uma camada de abstração de banco de dados &#8220;DAL&#8221;, que traduz nosso código Python em comandos SQL de acordo com o banco de dados definido na string de conexão. Isso é feito de maneira transparente, o que permite a mudança de SQLite para MySQL (por exemplo).</span></p>
<p><span style="font-size: small;">A sintaxe para modelagem de tabelas é:</span></p>
<pre class="brush:py">db.define_table(
        'mytable',
        Field('myfield1','string',required=true),
        Field('myfield2','integer',requires=IS_NOT_EMPTY())
        )</pre>
<p><span style="font-size: small;"> </span></p>
<p>Onde</p>
<p><strong>db</strong> é nossa referência para a instância da classe <strong>DAL,</strong> que por sua vez está ligada ao banco SQLite<br />
<strong>define_table</strong> é o método mais importante da classe DAL que instancia objetos do tipo Table &#8211; nossa tabela no banco de dados<br />
<strong>&#8216;mytable&#8217;</strong> é o nome que damos à tabela; este parâmetro será sempre o primeiro a ser passado ao método<br />
<strong>Field</strong> é outro método da classe DAL que define cada campo da tabela e recebe como parâmetros: nome do campo, tipo de dados e validadores (para informações detalhadas a respeito dos validadores, acesse o <a href="http://web2py.com/book/" target="_blank">web2py-book </a>- os validadores utilizados aqui serão autoexplicativos)</p>
<p><span style="font-size: small;">Vá até a última linha do arquivo, dê um enter e começaremos então a modelar as tabelas do nosso banco de dados <strong>&#8220;db&#8221;.</strong></span></p>
<p><span style="font-size: x-small;"><strong><span style="font-size: small;"><span style="font-weight: normal;">A primeira coisa que faremos é importar o módulo </span><span style="font-weight: normal;">datetime</span><span style="font-weight: normal;"> do Python. Este módulo se comunica com o sistema operacional e nos permite registrar a data e hora da postagem.</span></span></strong></span></p>
<p><span style="font-size: x-small;"><strong><span style="font-size: small;"><span style="font-weight: normal;">Na versão atual do framework, já é possível utilizar diretamente </span><span style="font-weight: normal;">o comando response.now</span><span style="font-weight: normal;"> para retornar data e hora. Apesar disso, quis mostrar aqui como importar um módulo py externo.</span></span></strong></span></p>
<p><span style="font-size: x-small;"><strong><span style="font-size: small;"><span style="font-weight: normal;">Após esta linha, modelaremos nossa principal tabela que irá conter os posts do blog.</span></span></strong></span></p>
<pre class="brush:py">import datetime
db.define_table(
         'posts',
         Field('post_title',notnull=True,required=True,
               requires=[IS_NOT_EMPTY(error_message=T('Fill the field!')),\
               IS_NOT_IN_DB(db, 'posts.post_title')]),
         Field('post_text', 'text'),
         Field('post_time', 'datetime', default=datetime.datetime.today()),
         Field('post_category',db.categories, required=True,
               requires = IS_IN_DB(db, 'categories.id', 'categories.category_name')),
         Field('author', db.auth_user, default=user_id)
)</pre>
<p><span style="font-size: small;"><br />
A tabela acima chama-se <strong>&#8216;posts&#8217;</strong><br />
Ela possui os campos:</span><br />
<span style="font-size: small;"><br />
<strong> &#8216;post_title&#8217;</strong> é do tipo &#8216;string&#8217; (definido automaticamente quando não informamos um tipo) e armazenará o<br />
título da postagem. Ele é um campo de preenchimento obrigatório -  note que neste exemplo coloquei 3 validadores para definir a obrigatoriedade, sendo eles:<br />
o <strong><span style="color: #ff0000;">notnull=True </span></strong>define a propriedade NOT NULL do banco de dados e não permite a inserção nula, retornando erro<br />
o <span style="font-size: small;"><span style="color: #ff0000;"><strong>required=True</strong></span> informa à classe DAL que esta é uma propriedade obrigatória. Este processo ocorre no nível do Controller, sendo assim, será validado mesmo que não exista um formulário (por exemplo, quando acessado via webservice ou xml-rpc)<br />
o </span><span style="font-size: small;"><strong><span style="color: #ff0000;">requires=IS_NOT_EMPTY(error_message=T(&#8216;Fill the field!&#8217;))</span></strong> define o validador de formulários, desta forma, quando criarmos um FORM utilizando os helpers do web2py, o formulário será automaticamente validado <img src='http://www.profissionaisti.com.br/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  e será exibida a mensagem &#8216;Fill the Field&#8217; (que poderá ser traduzida pelo T() para qualquer idioma previamente definido).</span></span></p>
<p><span style="font-size: small;"> &#8216;<strong>post_text&#8217;</strong> é do tipo &#8216;text&#8217;, responsável pela armazenagem do corpo do texto da postagem, e não será validado<br />
<strong> &#8216;post_time&#8217; </strong>é do tipo &#8216;datetime&#8217;, campo que recebe uma data no formato &#8216;YYYY-MM-DD HH:MM:SS&#8217;; seu valor padrão será a data atual<br />
<strong> &#8216;post_category&#8217;</strong> é um campo obrigatório que recebe a categoria da postagem<br />
<strong>&#8216;post_author</strong>&#8216; armazena o id do usuário logado no sistema </span></p>
<p><span style="font-size: small;"><span style="color: #0000ff;">Seguindo o mesmo esquema iremos modelar as demais tabelas, mas antes é preciso entender 2 novos conceitos do DAL no web2py:</span></span></p>
<p><span style="font-size: small;"><strong>&#8216;upload&#8217; </strong>- quando declaramos o campo do tipo &#8216;upload&#8217;, o web2py automaticamente cria um campo que recebe o path para um arquivo, desta forma, quando criarmos um formulário ele irá conter um controle de upload e este arquivo será salvo na pasta UPLOADS da aplicação &#8211; o web2py irá nomear automaticamente e criar a referência no banco de dados.</span></p>
<p><span style="font-size: small;"><strong>&#8216;db.&lt;reference_table&gt;&#8217;</strong> por exemplo, na tabela &#8216;posts&#8217; iremos ter um relacionamento com a tabela &#8216;categories&#8217;, onde a tabela posts receberá o id da categoria. Logo, o campo post_category será um campo que recebe o parâmetro &#8216;db.categories&#8217;, significando que existe um relacionamento do tipo &#8216;Um para Muitos&#8217; dessa tabela com a tabela categories (não se preocupe muito com isso, pois irá entender esse conceito na prática).</span></p>
<p><span style="font-size: small;">Também incluiremos mais um bloco de código que determina o <strong>user_id</strong> do usuário que está logado; o web2py já implementa automaticamente o sistema de autenticação, então apenas usuários logados poderão criar posts.</span></p>
<p><span style="font-size: small;">Colocaremos um campo do tipo <strong>&#8216;boolean&#8217; </strong>que receberá True ou False para o controle da moderação dos comentários.</span></p>
<p><span style="font-size: small;">Na sequência, definiremos mais algumas validações para o nível do formulário que nos permitirão o relacionamento entre as tabelas e a criação automática dos combo-box para preenchimento dos campos do formulário. </span></p>
<p><span style="font-size: small;"><strong>IS_EMAIL() </strong>garante que o valor inserido seja um e-mail válido</span><span style="font-size: small;"> <strong> </strong></span></p>
<p><span style="font-size: small;"><strong>IS_IN_DB(db.table,&#8217;table.field&#8217;)</strong> define que o valor deve estar contido em outra tabela<br />
</span></p>
<p><span style="font-size: small;"><strong>IS_NOT_IN_DB()</strong> define que o valor não pode estar contido em outra ou na mesma tabela, trata-se de um validador muito útil para evitar cadastros em duplicidade. Você perceberá que podemos definir os validadores diretamente na declaração do Field() (como fizemos na tabela posts) e que também podemos fazer isso no final do arquivo de Model (como será feito abaixo &#8211; *recomendado*)<br />
</span></p>
<p><span style="font-size: small;">Clique para ver a <a href="http://web2py.com/book/default/section/7/4" target="_blank">Listagem completa dos validadores </a> </span></p>
<p><span style="font-size: small;">As opções <strong>writable</strong> e <strong>readable, </strong>como os próprios nomes dizem, definem se o campo será visível ou editável nos formulários.</span></p>
<p><span style="font-size: small;">O código pronto do MODEL db.py deve ficar como o código abaixo. Caso não queira digitar todo o código, basta baixar e substituir o seu arquivo, que se encontra em web2py/applications/BLOG/models/db.py, pelo arquivo: [ download <a href="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/db.py_.zip">MODEL do BLOG db.py</a> ]</span></p>
<pre class="brush:py">import datetime

if auth.is_logged_in():
    user_id = auth.user.id
else:
    user_id = None

db.define_table(
        'categories',
        Field('category_name', required=True)
        )

db.define_table(
         'posts',
         Field('post_title',notnull=True,required=True,
               requires=[IS_NOT_EMPTY(error_message=T('Fill the field!')),\
               IS_NOT_IN_DB(db, 'posts.post_title')]),
         Field('post_text', 'text'),
         Field('post_time', 'datetime', default=datetime.datetime.today()),
         Field('post_category',db.categories, required=True,
               requires = IS_IN_DB(db, 'categories.id', 'categories.category_name')),
         Field('author', db.auth_user, default=user_id)
)

db.define_table(
        'comments',
         Field('post_id', db.posts, required=True),
         Field('comment_author'),
         Field('comment_author_email', required=True),
         Field('comment_author_website'),
         Field('comment_text', 'text', required=True),
         Field('comment_time', 'datetime', required=True,\
              default=datetime.datetime.today()),
         Field('approved','boolean')
               )

db.define_table(
        'document',
        Field('post_id', db.posts, required=True),
        Field('name'),
        Field('file', 'upload'),
        Field('created_on', 'datetime', default=request.now),
        Field('created_by', db.auth_user, default=user_id)
        )

db.posts.post_text.requires = IS_NOT_EMPTY()
db.posts.author.readable = False
db.posts.author.writable = False

db.comments.post_id.requires = IS_IN_DB(db, 'posts.id', '')
db.comments.comment_text.requires = IS_NOT_EMPTY()
db.comments.comment_author_email.requires = IS_EMAIL()
db.comments.comment_author_website.requires = IS_URL()
db.comments.post_id.readable = False
db.comments.post_id.writable = False

db.document.post_id.requires = IS_IN_DB(db, 'posts.id', '')
db.document.name.requires = [IS_NOT_EMPTY(), IS_NOT_IN_DB(db, 'document.name')]
db.document.post_id.readable = False
db.document.post_id.writable = False
db.document.created_by.readable = False
db.document.created_by.writable = False
db.document.created_on.readable = False
db.document.created_on.writable = False</pre>
<p>As 64 linhas acima definiram a modelagem do banco de dados, os relacionamentos e os validadores necessários para nossos formulários. Neste momento, você já pode se certificar de que o Model está salvo e, então, voltar à interface administrativa clicando em <strong>EDIT</strong> no menu superior do web2py.</p>
<p>Agora iremos executar uma aplicação chamada APPADMIN. Essa aplicação, que é acessada através do link <span style="color: #ff0000;">Database Administration</span>, é a responsável por gerenciar o banco de dados. Ao clicar no link, o web2py irá verificar se o banco de dados existe e, caso não exista, ele irá criar um automaticamente <img src='http://www.profissionaisti.com.br/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> . Esse processo ocorrerá também para cada tabela que definimos no modelo, e a qualquer momento que alterarmos o modelo das tabelas o web2py irá efetuar todas as alterações necessárias (você poderá verificar os comandos SQL executados clicando no link<span style="color: #ff0000;"> sql.log</span>).</p>
<p><span style="color: #ff0000;"><span style="color: #000000;"><a href="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-09-at-14.56.29.jpg"><img class="alignnone size-full wp-image-59" title="Screen shot 2010-06-09 at 14.56.29" src="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-09-at-14.56.29.jpg" alt="" width="516" height="95" /></a></span></span></p>
<p><span style="color: #000000;">Clique em <span style="color: #ff0000;">database administration</span> para ter acesso ao admin das tabelas, onde você poderá efetuar operações CRUD em suas tabelas e efetuar selects, joins e outros comandos de consulta (discutiremos depois). Note que o web2py já criou para você algumas tabelas de controle de usuários, grupos e autenticação.<br />
</span></p>
<p><span style="color: #ff0000;"><span style="color: #000000;"><a href="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-09-at-14.59.47.jpg"><img class="alignnone size-full wp-image-60" title="Screen shot 2010-06-09 at 14.59.47" src="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-09-at-14.59.47.jpg" alt="" width="395" height="543" /></a></span></span></p>
<p><span style="color: #000000;">Clicando no nome da tabela você verá a tela de pesquisa: nela poderá executar comandos do DAL que são equivalentes aos comandos SQL. Veja exemplos <a href="http://web2py.com/book/default/section/6/1" target="_blank">aqui</a> (os exemplos serão revistos no momento de criação dos Controllers).</span></p>
<p><span style="color: #ff0000;"><span style="color: #000000;">Clicando em <span style="color: #ff0000;">insert newcategories</span> você verá formulários de inserção criados automaticamente pelo web2py; insira 3 categorias apenas para teste (Receitas, Viagens, Fotos):</span></span></p>
<p><span style="color: #ff0000;"><span style="color: #000000;"><a href="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-09-at-17.37.16.jpg"><img class="alignnone size-full wp-image-62" title="Screen shot 2010-06-09 at 17.37.16" src="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-09-at-17.37.16.jpg" alt="" width="408" height="150" /></a></span></span></p>
<p><span style="color: #000000;">Se você já chegou até aqui, então significa que já temos o modelo das tabelas e o banco de dados prontos! Vamos passar para o Controller que será a camada lógica da nossa aplicação</span><span style="font-size: x-large;"><span><strong><span style="font-size: small;"><span style="font-weight: normal;"><br />
</span></span></strong></span></span></p>
<h2><span style="color: #000000;"> <strong> Controllers</strong></span></h2>
<p><span style="color: #000000;">Controller faz exatamente o que o nome diz: &#8220;controla&#8221; as ações da aplicação.</span><span style="color: #000000;"> Os Controllers definem as ACTIONS que, analisando de uma maneira bem simplificada, são funções Python. Se você já programa em Python deve conhecer a sintaxe de uma função ou método.</span></p>
<pre class="brush:py">def ActionName():
      [execute algum código]
      return [alguma resposta]</pre>
<p>Algumas regras devem ser seguidas na construção dos controllers. Obviamente que a primeira delas é a regra de endentação do Python, portanto, no controller é necessário escrever corretamente o código Python &#8211; se você não conhece muito a respeito de endentação, indico a leitura do post <a href="http://www.profissionaisti.com.br/2009/06/codifique-como-um-verdadeiro-pythonista/" target="_blank">Codifique como um verdadeiro pythonista</a> e do <a href="http://www.python.org/dev/peps/pep-0257/" target="_blank">PEP257</a>.</p>
<p>O web2py tem um esquema de mapeamento de URLs baseado nas actions, e este esquema funciona da seguinte forma:</p>
<p>http://127.0.0.1:8000/<span style="color: #ff6600;">BLOG</span>/<span style="color: #339966;">Controller</span>/<span style="color: #ff0000;">ActionName</span>/</p>
<p>Onde :</p>
<p><strong>http://&#8230;</strong> é o endereço do seu servidor<br />
<strong><span style="color: #ff6600;">BLOG</span></strong> é o nome da aplicação e o nome da pasta dentro de applications<br />
<strong><span style="color: #339966;">Controller</span></strong> é o nome do arquivo de controller ex. default.py, cadastros.py etc<br />
<strong><span style="color: #ff0000;">ActionName</span></strong> é o nome da action que você criou no controller</p>
<p><img class="alignnone" title="MVCw2p" src="http://web2py.com/book/static/book_image/gluon.png" alt="" width="480" height="360" /></p>
<p>Portanto, quando você define uma função Python que não recebe argumentos e retorna um dicionário ou um texto, o web2py irá expor esta função; se você não criar uma <strong>VIEW</strong> contendo o mesmo nome da função, o web2py irá utilizar a <strong>VIEW genérica</strong> e exibirá o output do conteúdo, além disso o web2py tem VIEWS genéricas que permitem fazer output do retorno de uma função via <strong>RSS, XML, JSON e HTML</strong> de forma automática.<br />
Mas você obviamente irá customizar o visual e os detalhes da apresentação, ou então irá contratar um designer para criar as VIEWS.</p>
<p>Algumas regras são estabelecidas no ambiente do web2py para expor as funções Python:</p>
<ol>
<li>Funcões que recebem argumentos ou que comecem com __ não são expostas; as funções __ActionNAme() e ActionName(param1,param2) podem ser acessadas via chamada interna, xml-rpc ou até mesmo via Ajax, mas não são expostas como views.</li>
<li>As actions devem retornar String ou algum outro objeto serializável, e geralmente optamos pelo retorno de um dicionário.</li>
</ol>
<p><strong>Vamos criar nosso primeiro controller:</strong></p>
<p>Lembre-se que para voltar à home do ADMIN, basta clicar em <strong>EDIT</strong> no menu superior do web2py. Depois, procure abaixo da seção Controllers o arquivo default.py e clique em edit:</p>
<p><a href="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-09-at-16.24.36.jpg"><img class="alignnone size-full wp-image-61" title="Screen shot 2010-06-09 at 16.24.36" src="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-09-at-16.24.36.jpg" alt="" width="430" height="153" /></a></p>
<p>Dentro do arquivo default.py, que é o nosso controller padrão, teremos algumas actions já definidas &#8211; não as altere, deixe-as  como estão. Comecemos alterando a função que expõe a View index.html, definida como def index(): no arquivo do controller.</p>
<p>Essa é nossa página inicial e, como é um blog, já começaremos exibindo os posts e as categorias. Repare que faremos acesso ao Model e executaremos queries que irão retornar os registros da tabela &#8216;posts&#8217; e da tabela categories; também será necessário exibir a quantidade de comentários para cada post e, para isso, executaremos um count() na tabela de comments.</p>
<p>Seu código deve ficar como o código abaixo (altere apenas o index(), não mude nada abaixo disso):</p>
<pre class="brush:py">#essas 2 linhas serão o titulo e subtitulo na view
response.title = T('My Blog')
response.subtitle = T('My blog is Python powered')

def index():
    #enviamos uma mensagem de boas vindas
    response.flash = T('Welcome to my BLOG')

    #retornando todos os posts ordenados descendentemente
    #aqui fazemos um Inner join entre as tabelas de posts e categories
    posts = db(db.categories.id==db.posts.post_category)\
                      .select(db.posts.ALL,db.categories.ALL,\
                                 orderby=~db.posts.post_time)

    # aqui retornamos as categorias e a contagem de posts de cada uma
    # Existem outras formas de fazer isso, mas preferi mostrar as diferentes possibilidades de retorno e iteração
    cats = db().select(db.categories.ALL)
    categories = []
    for cat in cats:
        count = len(db(
                   db.posts.post_category == cat.id
                   ).select(db.posts.ALL))
        categorie = {'id':cat.id,'name':cat.category_name,'posts':str(count)}
        categories.append(categorie)

    #aqui retornamos os dois objetos populados
    return dict(posts=posts,categories=categories)</pre>
<p>Já temos nosso Controller pronto para retornar o que precisamos para a View. Se você abrir o navegador e apontar para <a href="http://127.0.0.1:8000/BLOG/default/index" target="_blank">http://127.0.0.1:8000/BLOG/default/index</a>, verá a view default do web2py retornando os dados em formato de tabela, e mesmo que o seu controller não tenha uma view correspondente, o web2py irá utilizar a view genérica para exibir as variavéis &#8216;posts&#8217; e  &#8217;categories&#8217; que foram retornadas (isso é muito útil para debug).</p>
<p>Agora vamos trabalhar esse retorno para colocá-lo em um layout mais apresentavél.</p>
<p><strong>Views</strong></p>
<p>No web2py o template das views é marcado utilizando linguagem Python, e podemos fazer quase tudo que faríamos em um programa Python ou Controller diretamente dentro da View. Apesar de ser recomendado deixar a lógica toda no Controller, às vezes é muito útil colocar um pouco de inteligência nas Views.</p>
<p>O padrão para marcação segue os modelos abaixo, e os demais detalhes veremos no decorrer do tutorial:</p>
<ol>
<li>O código da view não precisa seguir regras de endentacão do Python</li>
<li>A marcação para escape é feita dentro de {{ e }}</li>
<li>Blocos de código começam nas linhas {{}} terminadas em :</li>
<li>Blocos de código teminam onde encontram a instrução {{pass}}</li>
<li>Nos casos em que a construção do bloco for clara, não será preciso usar o {{pass}}</li>
</ol>
<p>Exemplo de uso:</p>
<pre class="brush:html">&lt;div class="header"&gt;
&lt;H1&gt;{{=meutitulo}}&lt;/H!&gt;
{{bands = ['Dream Theater','Gathering','Morcheeba']}}
&lt;ul&gt;
{{for band in bands: }}
&lt;li&gt;{{=band}}&lt;/li&gt;
{{pass}}
&lt;/ul&gt;
&lt;/div&gt;</pre>
<p>Resultará em:</p>
<pre class="brush:html">&lt;div class="header&gt;
&lt;H1&gt;TITULO AQUI&lt;/H1&gt;
&lt;ul&gt;
&lt;li&gt;Dream Theater&lt;/li&gt;
&lt;li&gt;Gathering&lt;/li&gt;
&lt;li&gt;Morcheeba&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;</pre>
<p>O mesmo resultado poderia ser obtido em uma única linha com o uso de HTML Helpers:</p>
<pre class="brush:html">{{=DIV(H1(meutitulo),UL(*[LI(*band) for band in bands ]),_class='header')}}</pre>
<p>Veja como o web2py faz para converter as views em output HTML:</p>
<p>O código abaixo&#8230;</p>
<pre class="brush:html">&lt;html&gt;&lt;body&gt;
{{for x in range(10):}}{{=x}}hello&lt;br /&gt;{{pass}}
&lt;/body&gt;&lt;/html&gt;</pre>
<p>&#8230; será convertido em:</p>
<pre class="brush:py">response.write(" &lt;html&gt;&lt;body&gt; ", escape=False)
for x in range(10):
    response.write(x)
    response.write("""hello &lt;br /&gt;""", escape=False)
response.write(" &lt;/body&gt;&lt;/html&gt; ", escape=False)</pre>
<p>Para facilitar, o web2py permite a definição de um arquivo de layout padrão, que possa ser usado como &#8220;MAster-Page&#8221; para todas as outras views através da utilização das cláusulas {{extend}}  e {{include}}.</p>
<p>Um pequeno exemplo de view que estende um layout padrão:<br />
Código da View:</p>
<pre class="brush:html">{{extend meulayout.html}}
&lt;H1&gt;Olá Mundo {{=minhasVariaveis}}&lt;/H1&gt;
{{include outrapagina.html}}</pre>
<p>O layout padrão a ser estendido deve conter a cláusula {{include}}, para servir de placeholder para o conteúdo renderizado na view.<br />
Código do arquivo meulayout.html:</p>
<pre class="brush:html">&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Page Title&lt;/title&gt;
&lt;/head&gt;
  &lt;body&gt;
    {{include}}
  &lt;/body&gt;
&lt;/head&gt;</pre>
<p>Para facilitar nosso trabalho, deixei pronto o código do layout padrão para o blog, que resultará em:</p>
<p><a href="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-10-at-12.22.25.jpg"><img class="alignnone size-medium wp-image-63" title="Screen shot 2010-06-10 at 12.22.25" src="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-10-at-12.22.25-300x253.jpg" alt="" width="300" height="253" /></a></p>
<p>Sei que não é a coisa mais linda do mundo, mas nada que um designer não possa dar um jeito com CSS! <img src='http://www.profissionaisti.com.br/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Faça o download do arquivo [ <a href="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/bloglayout.html.zip">bloglayout.html</a> ] e o descompacte para <strong><em>web2py/applications/BLOG/views/bloglayout.html</em></strong>. Esse é o arquivo de layout padrão que iremos utilizar em nossas views; vamos entender o conteúdo principal dele:</p>
<p>bloglayout:</p>
<p>Logo no início visualizamos o comando {{include}}, utilizado para a inclusão do arquivo web2py_ajax.html, que engloba a JQUERY e muitas funções para trabalhar com Ajax.</p>
<p>Este layout é um pouco diferente do comum, pois precisamos declarar mais de um placeholder na página, necessitamos de um local para incluir o conteúdo principal e outro para a inclusão dos itens da barra lateral. Por conta destas particularidades, colocaremos a cláusula {{include}} logo no inicio do &lt;body&gt;. O layout também contém uma DIV com a classe &#8220;flash&#8221;, que servirá para exibir mensagens de notificação.</p>
<pre class="brush:html">&lt;body&gt;
{{include}}
&lt;div&gt;{{=response.flash or ''}}&lt;/div&gt;
&lt;body&gt;{{include}}&lt;div&gt;{{=response.flash or ''}}&lt;/div&gt;</pre>
<p>Placeholder para o conteúdo da barra lateral, que será renderizado pela View e declarado na função sidebar():</p>
<pre class="brush:html">&lt;div class="categories"&gt;

{{if 'sidebar' in globals(): sidebar()}}

&lt;/div&gt;</pre>
<p>Após a visualização do código acima, será exibida uma sequência de código que define os links para a administração de usuário, login e senha (falaremos sobre Auth na segunda parte deste tutorial).</p>
<p>Na sequência, teremos um placeholder que será o responsável por receber o conteúdo principal das views &#8211; definido na função maincontent():</p>
<pre class="brush:html">&lt;div class="col2"&gt;

{{maincontent()}}

&lt;/div&gt;</pre>
<p>Agora que esse arquivo já está no diretório de Views, podemos editar a View que responde para a função index() do nosso controller default.py, acessível através da URL <a href="http://127.0.0.1:8000/BLOG/default/index" target="_blank">http://127.0.0.1:8000/BLOG/default/index</a>. O web2py irá automaticamente rotear a chamada da URL <strong>/<span style="color: #0000ff;">default</span>/<span style="color: #ff0000;">index</span></strong> para o controller d<span style="color: #0000ff;">efault.py</span>. Dentro do <span style="color: #0000ff;">default.py</span> ele procurará uma função exposta com o nome <strong><span style="color: #ff0000;">index() </span></strong>e irá executar este método.</p>
<p>Então, irá procurar na pasta de Views o arquivo <span style="color: #0000ff;">default</span>/<span style="color: #ff0000;">index.html <span style="color: #000000;">e executará o código Python + HTML deste arquivo, respondendo ao navegador.</span></span></p>
<p><span style="color: #ff0000;"><span style="color: #000000;">Dentro da view, as variáveis de retorno do controller, as variáveis globais, os objetos response e request, entre outras coisas, ficarão acessíveis.</span></span></p>
<p><span style="color: #ff0000;"><span style="color: #000000;">Edite a view default/index.html de acordo com o código abaixo:</span></span></p>
<pre class="brush:html">{{def sidebar():}}
        &lt;h1&gt;{{=T('Sidebar')}}&lt;/h1&gt;
        &lt;h3&gt;{{=T('Categories')}}&lt;/h3&gt;
        {{if auth.user:}}
                [ {{=A(T('Add Category'),
                        _href=URL(r=request,c='default',f='addcategory'))}} ]
        {{pass}}
        &lt;ul&gt;
        {{for categorie in categories:}}
                {{=LI(A(categorie['name']+' ('+categorie['posts']+')',
                        _href=URL(r=request, f='categoryposts', args=categorie['id'])))}}
        {{pass}}
        &lt;/ul&gt;
{{return}}</pre>
<p><span><br />
Nessa primeira parte definimos a função sidebar() que será renderizada em nosso placeholder sidebar, definido no arquivo de layout.</span></p>
<p><span><strong>Linhas 2 e 3:</strong> exibimos um título e um subtítulo, inseridos na função T() &#8211; função que serve para internacionalizar strings (na segunda parte do tutorial falaremos dela)<br />
<strong>Linhas 4 a 7:</strong> verificamos se o usuário está logado e, em caso positivo, exibimos o link para as funções AddCategory e AddPost que iremos criar em nosso Controller<br />
<strong>Linhas 8 a 13 :</strong> Varremos a coleção de categorias retornadas pelo Controller e exibimos o nome e a contagem de posts para cada categoria. Existem inúmeras maneiras de se fazer isso, mas optei por esta forma para mostrar uma outra possibilidade</span></p>
<p><span>No código abaixo, iremos definir a função maincontent() que será nosso conteúdo principal, responsável pela exibição das postagens, detalhes das postagens e contagem de comentários. Colocaremos links para funções de exibição individual de posts, exibição de comentários e edição de posts (vou dividir em pequenas partes para facilitar o entendimento).</span></p>
<pre class="brush:html">{{def maincontent():}}
        &lt;h1&gt;{{=T('Blog Posts')}}&lt;/h1&gt;
        {{for item in posts:}}
                {{=H1(A(item.posts.post_title,
                       _href=URL(r=request, f='showpost', args=item.posts.id)))}}
               &lt;small&gt;{{=item.posts.post_time.strftime("%d/%m/%Y")}}&lt;/small&gt;
               {{=P(XML(item.posts.post_text,sanitize=True))}}</pre>
<p><span><br />
Linha  1: definimos a função maincontent()<br />
Linha  2: exibimos um título<br />
Linha  3: iniciamos um Loop for nos itens da coleção de posts retornada<br />
Linhas 4 a 5: Exibimos o título da postagem com permalink para exibição do post<br />
Linha  6: exibimos a data de postagem formatada<br />
Linha 7: Criamos um parágrafo com um parser XML para a exibição do texto de cada postagem, considerando tags HTML. O sanitize=True serve para prevenir inserção de código malicioso<br />
</span></p>
<pre class="brush:html">              &lt;p class="postmetadata"&gt;
                      {{=T('Posted in %s',item.categories.category_name)}} |
                             {{if auth.user:}}
                                    {{=A(T('Edit'),
                                              _href=URL(r=request, f='editpost', args=item.posts.id))}}|

                             {{pass}}

                        {{count = db.posts.id.count()}}
                        {{for row in db((db.posts.id==db.comments.post_id)&amp;\
                                                (db.posts.id==item.posts.id))\
                                                 .select(db.posts.ALL, count, groupby=db.posts.id):}}

                                 {{count = row._extra[count]}}
                         {{pass}}

                         {{try:}}
                                  {{=A(T('Comments %s', int(count)),
                                         _href=URL(r=request, f='showpost', args=item.posts.id)+'#comments')}}
                         {{except TypeError:}}
                                  {{=T('No Comments')}}
                         {{pass}}
             &lt;/p&gt;
         {{pass}}
{{return}}</pre>
<p><span><br />
Aqui criamos uma DIV para exibir os metadados da postagem (Postado em | Edit| Comentários X)<br />
Linha 2: Mostrado em qual categoria o post está inserido<br />
Linha 3 a 8: Caso o usuário esteja logado, damos a opção de editar a postagem<br />
Linhas 10 a 23: Efetuamos a contagem de comentários para cada post e a exibimos &#8211; aqui utilizamos uma outra maneira para efetuar count()<br />
Finalizamos o Loop e retornamos a função<br />
</span></p>
<pre class="brush:html">{{extend 'bloglayout.html'}}</pre>
<p><span> A linha acima estende o arquivo de layout padrão, deixando as funções </span><strong>sidebar()</strong><span> e </span><strong>maincontent()</strong><span> disponíveis para serem chamadas em seus placeholders.</span></p>
<p>Você pode fazer o download do arquivo [ <a href="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/index.html.zip">index.html</a>]  e descompactar para <strong>/web2py/applications/BLOG/views/default/index.html</strong></p>
<p><strong>Neste momento seu blog já deverá estar funcionando, porém não irá exibir nenhum post, ao menos que você efetue o cadastro via APPADMIN.</strong></p>
<p>Vamos criar agora duas funções dentro do Controller default.py, que permitirão <strong>Adicionar Categorias</strong>, <strong>Adicionar Posts</strong>, <strong>Exibir Posts</strong> e <strong>Adicionar Comentários.</strong></p>
<p><strong><span style="font-weight: normal;">Criaremos os formulários automaticamente, utilizando o helper</span> SQLFORM();</strong> ele cria os campos do formulário de acordo com o modelo de dados e regras de validação que já estabelecemos no model.</p>
<p>Dentro do default.py crie as funções conforme o código abaixo (explicação nos comentários):</p>
<pre class="brush:py">#decorator que exige login para acesso a esta função
@auth.requires_login()
def addcategory():
       form = SQLFORM(db.categories)
       if form.accepts(request.vars, session):
                   response.flash = 'form accepted'
       return dict(form=form)

#decorator que exige login para acesso a esta função
@auth.requires_login()
def addpost():
      form = SQLFORM(db.posts)
      if form.accepts(request.vars, session):
                  response.flash = 'form accepted'
      return dict(form=form)

def showpost():
      #recebemos o parametro do ID do post e carregamos o registro referente
      post = db.posts[request.args(0)]
      #se não tiver parametro/post selecionado então redirecionamos
      if not post:
           redirect(URL(r=request, f='index'))
      #definimos o parametro para query na tabela de comentários ( dentro deste escopo)
      db.comments.post_id.default = post.id
      #propriedades adicionais do form enquanto ainda nào temos admin de comments
      db.comments.approved.default = True
      db.comments.approved.readable = False
      db.comments.approved.writable = False
      #criamos o formulário para inclusão de posts
      form = crud.create(db.comments)
      #retornamos os comentários já existentes para este post
      comments = db(db.comments.post_id==post.id).select()
      #retornamos para a view
      return dict(post=post,comments=comments,form=form)</pre>
<p>Se preferir, faça o download do arquivo default.py aqui: [ <a href="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/default.py_.zip">default.py</a>]</p>
<p>Crie agora uma view para cada uma das funções criadas acima:</p>
<p><a href="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-10-at-16.30.38.jpg"><img class="alignnone size-full wp-image-66" title="Screen shot 2010-06-10 at 16.30.38" src="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-10-at-16.30.38.jpg" alt="" width="459" height="293" /></a></p>
<p>As views criadas serão: default/index.html, default/addpost.html, default/addcategory.html, default/showpost.html</p>
<p><a href="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-10-at-16.33.35.jpg"><img class="alignnone size-full wp-image-67" title="Screen shot 2010-06-10 at 16.33.35" src="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-10-at-16.33.35.jpg" alt="" width="441" height="79" /></a></p>
<p>Para cada uma dessas views, que já devem estar funcionando, iremos editar e estender o layout padrão <strong>bloglayout.html</strong></p>
<p>Edite os arquivos:</p>
<p><strong>default/addpost.html</strong></p>
<pre class="brush:html">{{def maincontent():}}
    &lt;h1&gt;{{=T('Add a post')}}&lt;/h1&gt;
        {{=form}}
{{return}}
{{extend 'bloglayout.html'}}</pre>
<p>default/addcategory.html</p>
<pre class="brush:html">{{def maincontent():}}
    &lt;h1&gt;{{=T('Add a category')}}&lt;/h1&gt;
        {{=form}}
{{return}}
{{extend 'bloglayout.html'}}</pre>
<p>default/showpost.html</p>
<pre class="brush:html">{{def maincontent():}}
    &lt;div class="post"&gt;
        &lt;h1&gt;{{=post.post_title}}&lt;/h1&gt;
         {{=P(XML(post.post_text,sanitize=True))}}
    &lt;/div&gt;

    &lt;div class="comments"&gt;
        &lt;h2&gt;{{=T('Comments on this post')}}&lt;/h2&gt;
            {{for comment in comments:
                response.write(DIV(comment.comment_author,\
                    UL(LI(comment.comment_text))))
            pass}}

    &lt;h3&gt;{{=T('Post a comment')}}&lt;/h3&gt;

    {{=form}}

    &lt;/div&gt;
{{return}}

{{extend 'bloglayout.html'}}</pre>
<p><span>Agora seu blog já está funcionando, você já pode adicionar posts, adicionar categorias, incluir comentários nos posts.</span></p>
<p><strong>Visao geral</strong></p>
<p><span>O layout que criamos não ficou uma maravilha, mas um designer com experiência em HTML e CSS pode facilmente customizar tudo, inclusive os formulários e Helpers<br />
Repare que em todos os formulários o web2py criou os validadores de campos. Tente entrar com um e-mail incorreto, uma URL ilegal ou um campo obrigatório vazio para constatar.</span></p>
<p>O web2py também utiliza JQuery para criar DatePickers automaticamente para os campos do tipo &#8216;datetime&#8217; e &#8216;date&#8217;:</p>
<p><a href="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-10-at-17.51.54.jpg"><img class="alignnone size-full wp-image-75" title="Screen shot 2010-06-10 at 17.51.54" src="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-10-at-17.51.54.jpg" alt="" width="332" height="216" /></a></p>
<p><span>Caso não esteja logado, o web2py exige que o usuário efetue login para poder cadastrar posts e categorias.</span></p>
<p><span>default/index</span></p>
<p><a href="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-10-at-17.29.35.jpg"><img class="alignnone size-medium wp-image-70" title="Screen shot 2010-06-10 at 17.29.35" src="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-10-at-17.29.35-300x263.jpg" alt="" width="300" height="263" /></a></p>
<p>default/addcategory</p>
<p><a href="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-10-at-17.30.58.jpg"><img class="alignnone size-medium wp-image-71" title="Screen shot 2010-06-10 at 17.30.58" src="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-10-at-17.30.58-300x130.jpg" alt="" width="300" height="130" /></a></p>
<p>default/addpost</p>
<p><a href="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-10-at-17.31.41.jpg"><img class="alignnone size-medium wp-image-72" title="Screen shot 2010-06-10 at 17.31.41" src="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-10-at-17.31.41-300x195.jpg" alt="" width="300" height="195" /></a></p>
<p>default/showpost</p>
<p><a href="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-10-at-17.33.04.jpg"><img class="alignnone size-medium wp-image-73" title="Screen shot 2010-06-10 at 17.33.04" src="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/Screen-shot-2010-06-10-at-17.33.04-272x300.jpg" alt="" width="272" height="300" /></a></p>
<p>Aqui você pode fazer o download da aplicação [ <a href="http://rochacbruno.com.br/blog/wp-content/uploads/2010/06/BLOG.w2p.zip">BLOG.w2p</a> ], basta importar no admin do web2py.</p>
<p>Nas próximas partes deste tutorial, que serão publicadas em breve, iremos efetuar as seguintes alterações:</p>
<ol>
<li>Inclusão das funções de listagem de categorias (categoryposts)</li>
<li>Formatação dos comentários com markdown</li>
<li>Upload de imagens e documentos</li>
<li>Busca via Ajax com auto complete</li>
<li>Internacionalização</li>
<li>Melhorias na autenticação de usuários</li>
<li>Publicação de feed RSS</li>
<li>Output em formatos XML e CSV</li>
<li>Integração com o Twitter</li>
</ol>
<p>Espero que este post tenha sido útil para quem está começando com o web2py.<br />
Qualquer dúvida, elogio ou sugestão é só comentar!</p>
<p>Obrigado</p>
<p>[]&#8216;s</p>
<p>Referência: <a href="http://rochacbruno.com.br/blog/2010/06/desenvolvimento-com-web2py-tutorial-pt1/" target="_blank">http://rochacbruno.com.br/blog/2010/06/desenvolvimento-com-web2py-tutorial-pt1/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.profissionaisti.com.br/2010/06/primeiros-passos-no-desenvolvimento-com-o-web2py-tutorial-parte-1/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Otimizando projetos em Django com select_related</title>
		<link>http://www.profissionaisti.com.br/2009/11/otimizando-projetos-em-django-com-select_related/</link>
		<comments>http://www.profissionaisti.com.br/2009/11/otimizando-projetos-em-django-com-select_related/#comments</comments>
		<pubDate>Thu, 05 Nov 2009 10:25:38 +0000</pubDate>
		<dc:creator>Francisco Souza</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Desenvolvimento Web]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.profissionaisti.com.br/?p=4690</guid>
		<description><![CDATA[Um dos problemas que vemos na utilização &#8220;padrão&#8221; do Django é a ausência do famigerado join nas consultas geradas pelo ORM do framework. Isto pode ser notado em um exemplo clássico: uma classe de modelo, chamada Pessoa, que tem um relacionamento com outra classe de modelo chamada Carro, bem simples, uma pessoa tem um carro. [...]]]></description>
			<content:encoded><![CDATA[<p>Um dos problemas que vemos na utilização &#8220;padrão&#8221; do Django é a ausência do famigerado <em>join</em> nas consultas geradas pelo ORM do framework. Isto pode ser notado em um exemplo clássico: uma classe de modelo, chamada Pessoa, que tem um relacionamento com outra classe de modelo chamada Carro, bem simples, uma pessoa tem um carro. São executadas duas consultas no banco de dados quando o seguinte código é executado:</p>
<p><code>p = Pessoa.objects.get(id=1)<br />
carro = p.carro</code></p>
<p>Na primeira consulta, o Django busca na tabela de pessoas um registro único no qual o atributo id tem valor 1. Na segunda consulta, o Django busca na tabela de carros o carro que possui o valor da foreign key correspondente ao id do objeto <em>p</em> (instância da classe Pessoa).</p>
<p>Partindo deste pressuposto, é possível ver um número muito grande de problemas. Se for dado um novo modelo de classes, com seis classes: Cliente, Bairro, Cidade, UF, Pais e Continente. Essas classes possuem relacionamentos em cascata: Cliente com Bairro, Bairro com Cidade, e assim sucessivamente, até Continente. Qual seria o comportamento do Django ao tentar acessar o continente de um determinado cliente? O interpretador interativo do Python responde esta questão de maneira bem simples:</p>
<p><code>&gt;&gt;&gt; cliente = Cliente.objects.get(id=1)<br />
&gt;&gt;&gt; continente = cliente.bairro.cidade.uf.pais.continente<br />
&gt;&gt;&gt; from django.db import connection<br />
&gt;&gt;&gt; queries = connection.queries<br />
&gt;&gt;&gt; for query in queries:<br />
...        print query<br />
...<br />
{'time': '0.003', 'sql': u'SELECT "clientes_cliente"."id", "clientes_cliente"."nome", "clientes_cliente"."idade", "clientes_cliente"."bairro_id" FROM "clientes_cliente" WHERE "clientes_cliente"."id" = 1 '}<br />
{'time': '0.000', 'sql': u'SELECT "clientes_bairro"."id", "clientes_bairro"."nome", "clientes_bairro"."cidade_id" FROM "clientes_bairro" WHERE "clientes_bairro"."id" = 1 '}<br />
{'time': '0.000', 'sql': u'SELECT "clientes_cidade"."id", "clientes_cidade"."nome", "clientes_cidade"."uf_id" FROM "clientes_cidade" WHERE "clientes_cidade"."id" = 1 '}<br />
{'time': '0.000', 'sql': u'SELECT "clientes_uf"."id", "clientes_uf"."sigla", "clientes_uf"."pais_id" FROM "clientes_uf" WHERE "clientes_uf"."id" = 1 '}<br />
{'time': '0.000', 'sql': u'SELECT "clientes_pais"."id", "clientes_pais"."nome", "clientes_pais"."continente_id" FROM "clientes_pais" WHERE "clientes_pais"."id" = 1 '}<br />
{'time': '0.000', 'sql': u'SELECT "clientes_continente"."id", "clientes_continente"."nome" FROM "clientes_continente" WHERE "clientes_continente"."id" = 1 '}<br />
&gt;&gt;&gt;</code></p>
<p>Aí está a resposta quanto ao comportamento do Django: duas linhas de código, seis consultas ao banco de dados. Se esta fosse uma informação muito importante em um sistema, é possível notar o quão doloroso seria manter tudo isso num banco de dados relacional. É necessária uma abordagem diferente, com apenas um join seis consultas virariam apenas uma e o programador poderia dormir sem medo do DBA.</p>
<p>A instrução <em>select_related</em> responde à esta necessidade: ao ver esta instrução, o Django sabe que ele tem que fazer os joins, e que ele deve &#8220;passear&#8221; por todos os relacionamentos obtendo os dados. Se o cliente for buscado no banco de dados utilizando <em>select_related</em>, o objeto estará completamente em memória, e não será necessário acessar o banco de dados novamente para obter informações de nenhum dos relacionamentos, o interpretador interativo prova isso:</p>
<p><code>&gt;&gt;&gt; cliente = Cliente.objects.select_related().get(id=1)<br />
&gt;&gt;&gt; continente = cliente.bairro.cidade.uf.pais.continente<br />
&gt;&gt;&gt; from django.db import connection<br />
&gt;&gt;&gt; queries = connection.queries<br />
&gt;&gt;&gt; for query in queries:<br />
...         print query<br />
...<br />
{'time': '0.010', 'sql': u'SELECT "clientes_cliente"."id", "clientes_cliente"."nome", "clientes_cliente"."idade", "clientes_cliente"."bairro_id", "clientes_bairro"."id", "clientes_bairro"."nome", "clientes_bairro"."cidade_id", "clientes_cidade"."id", "clientes_cidade"."nome", "clientes_cidade"."uf_id", "clientes_uf"."id", "clientes_uf"."sigla", "clientes_uf"."pais_id", "clientes_pais"."id", "clientes_pais"."nome", "clientes_pais"."continente_id", "clientes_continente"."id", "clientes_continente"."nome" FROM "clientes_cliente" INNER JOIN "clientes_bairro" ON ("clientes_cliente"."bairro_id" = "clientes_bairro"."id") INNER JOIN "clientes_cidade" ON ("clientes_bairro"."cidade_id" = "clientes_cidade"."id") INNER JOIN "clientes_uf" ON ("clientes_cidade"."uf_id" = "clientes_uf"."id") INNER JOIN "clientes_pais" ON ("clientes_uf"."pais_id" = "clientes_pais"."id") INNER JOIN "clientes_continente" ON ("clientes_pais"."continente_id" = "clientes_continente"."id") WHERE "clientes_cliente"."id" = 1 '}<br />
&gt;&gt;&gt; </code></p>
<p>Problema de consultas resolvido, DBA feliz = programador feliz = cliente feliz! <img src='http://www.profissionaisti.com.br/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.profissionaisti.com.br/2009/11/otimizando-projetos-em-django-com-select_related/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>jQuery Tools &#8211; Mais uma boa opção para desenvolvedores web</title>
		<link>http://www.profissionaisti.com.br/2009/06/jquery-tools-mais-uma-boa-opcao-para-desenvolvedores-web/</link>
		<comments>http://www.profissionaisti.com.br/2009/06/jquery-tools-mais-uma-boa-opcao-para-desenvolvedores-web/#comments</comments>
		<pubDate>Thu, 11 Jun 2009 18:01:50 +0000</pubDate>
		<dc:creator>Jackson Caset</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[JQuery]]></category>
		<category><![CDATA[Tendências]]></category>
		<category><![CDATA[Desenvolvimento Web]]></category>
		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://www.profissionaisti.com.br/?p=2699</guid>
		<description><![CDATA[Olá PTI&#8217;s Sendo um desenvolvedor web, tenho a obrigação de ficar sabendo de tudo que sai de novo pela rede a fora, e hoje, acabei conhecendo mais uma biblioteca bacanetz que utiliza o framework jQuery e que promete nos ajudar em tarefas executadas quase que diariamente. A jQuery Tools é uma biblioteca que possui alguns [...]]]></description>
			<content:encoded><![CDATA[<p>Olá PTI&#8217;s</p>
<p>Sendo um desenvolvedor web, tenho a obrigação de ficar sabendo de tudo que sai de novo pela rede a fora, e hoje, acabei conhecendo mais uma biblioteca bacanetz que utiliza o framework jQuery e que promete nos ajudar em tarefas executadas quase que diariamente.</p>
<p>A <strong>jQuery Tools</strong> é uma biblioteca que possui alguns dos componentes javascript mais utilizados atualmente em websites e aplicações web, tais como: navegação em abas, tooltips, janelas modais e outros.</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-2700" title="jQuery Tools!" src="http://www.profissionaisti.com.br/wp-content/uploads/2009/06/jquery-tools.jpg" alt="jQuery Tools!" width="446" height="209" /></p>
<p>A biblioteca pode chegar a apenas 5.8KB se utilizadas formas de compressão de código eficientes e pode ser configurada, estilizada e extendida da forma que o programador desejar. Possui uma boa documentação e um fórum ativo para tirarmos quaisquer dúvidas, reportarmos problemas e etc.</p>
<p>A jQuery Tools é open source sobre as licenças MIT e GPL 2+.</p>
<p>Interessado em conhecê-la? <a href="http://flowplayer.org/tools/index.html" target="_blank">Acesse o site da biblioteca</a> e após seus testes deixe suas impressões comentadas abaixo.</p>
<p>Espero que seja útil <img src='http://www.profissionaisti.com.br/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.profissionaisti.com.br/2009/06/jquery-tools-mais-uma-boa-opcao-para-desenvolvedores-web/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Instalando o Apache, PHP e MySQL no Ubuntu Linux</title>
		<link>http://www.profissionaisti.com.br/2009/01/instalando-o-apache-php-e-mysql-no-ubuntu-linux/</link>
		<comments>http://www.profissionaisti.com.br/2009/01/instalando-o-apache-php-e-mysql-no-ubuntu-linux/#comments</comments>
		<pubDate>Mon, 19 Jan 2009 11:19:03 +0000</pubDate>
		<dc:creator>Klaus Peter Laube</dc:creator>
				<category><![CDATA[Software Livre]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[Desenvolvimento Web]]></category>
		<category><![CDATA[Ferramentas]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[tutoriais]]></category>

		<guid isPermaLink="false">http://www.profissionaisti.com.br/?p=508</guid>
		<description><![CDATA[Olá pessoal! Continuando o post sobre desenvolvimento web com software livre, hoje fica a dica sobre a instalação do Apache, PHP e MySQL (servidor web, linguagem de programação web e banco de dados, respectivamente) no Ubuntu. Estas três ferramentas são basicamente o ambiente de desenvolvimento mais utilizado para a Web, principalmente em se tratando de [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_511" class="wp-caption alignleft" style="width: 310px"><a href="http://www.profissionaisti.com.br/wp-content/uploads/2009/01/logo-trio.jpg"><img class="size-medium wp-image-511" src="http://www.profissionaisti.com.br/wp-content/uploads/2009/01/logo-trio-300x86.jpg" alt="Logotipos Apache, PHP e MySQL" width="300" height="86" /></a><p class="wp-caption-text">Logotipos: Apache, PHP e MySQL</p></div>
<p>Olá pessoal!</p>
<p>Continuando o post sobre <a title="Leia sobre desenvolvimento web com Software Livre" href="http://www.profissionaisti.com.br/2008/12/desenvolvimento-web-com-software-livre/">desenvolvimento web com software livre</a>, hoje fica a dica sobre a instalação do Apache, <a title="PHP não é coisa de moleque" href="http://www.profissionaisti.com.br/2009/01/concordo-plenamente-php-nao-e-coisa-de-moleque/" target="_blank">PHP</a> e MySQL (servidor web, linguagem de programação web e banco de dados, respectivamente) no <a title="Apresentando o Ubuntu" href="http://www.profissionaisti.com.br/2008/12/apresentando-o-ubuntu/" target="_blank">Ubuntu</a>.</p>
<p>Estas três ferramentas são basicamente o ambiente de desenvolvimento mais utilizado para a Web, principalmente em se tratando de plataformas Unix. É claro que tutoriais sobre este assunto é o que não falta na internet, por isso segue uma lista de fontes que foram fundamentais para a criação do meu &#8220;workspace&#8221;:</p>
<ul>
<li>André Gondim, Viva o Linux &#8211; <a title="Leia mais no Viva o Linux" href="http://www.vivaolinux.com.br/dica/Ubuntu-+-Apache2-+-MySQL-+-PHP5/" target="_blank">Linux: Ubuntu + Apache2 + MySQL + PHP5</a></li>
<li>Alexandre Gomes Gaigalas, Acorda pra Web! &#8211; <a title="Leia mais no Acorda pra Web!" href="http://gaigalas.net/Artigos/UbuntuServidorPHPMySQL.html" target="_blank">Tutorial de instalação do Apache, PHP e MySQL no Ubuntu</a></li>
<li>Vinícius Figueiredo, vinicius. &#8211; <a title="Leia mais no vinicius.figueiredo" href="http://vinicius.oitobits.net/arquivo/instalando-lamp-apache-mysql-e-php-no-ubuntu/" target="_blank">Instalando LAMP (Apache, MySQL e PHP) no Ubuntu</a></li>
<li>Apache Friends &#8211; <a title="Leia mais no Apache Friends" href="http://www.apachefriends.org/en/xampp.html" target="_blank">XAMPP</a></li>
<li>Joomla! Documentation &#8211; <a title="Leia mais na documentação do Joomla!" href="http://docs.joomla.org/Setting_up_your_workstation_for_Joomla!_development" target="_blank">Setting up your workstation for Joomla! development</a></li>
<li>Fórum Webly &#8211; <a title="Leia mais no Webly" href="http://forum.webly.com.br/index.php?showtopic=24313" target="_blank">Remover Apache &#8211; Mysql &#8211; PHP do Ubuntu</a></li>
<li>Netbeans.org &#8211; <a title="Leia mais no Netbeans.org" href="http://www.netbeans.org/kb/docs/php/configure-php-environment-ubuntu_pt_BR.html" target="_blank">Instalando e configurando PHP, Apache e MySQL para desenvolvimento de PHP no Ubuntu</a></li>
<li>Gerry IIagan, Gerry &#8211; <a title="Leia mais no gerry.ws" href="http://gerry.ws/2008/12/436/how-to-install-apache-mysql-php-on-ubuntu-linux-desktop.html" target="_blank">How to install Apache, MySQL, PHP on Ubuntu Linux Desktop</a></li>
</ul>
<p>Fica a dica&#8230;</p>
<p>Até a próxima&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.profissionaisti.com.br/2009/01/instalando-o-apache-php-e-mysql-no-ubuntu-linux/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Google e o desenvolvimento de aplicações ricas para a Internet</title>
		<link>http://www.profissionaisti.com.br/2009/01/google-e-o-desenvolvimento-de-aplicacoes-ricas-para-a-internet/</link>
		<comments>http://www.profissionaisti.com.br/2009/01/google-e-o-desenvolvimento-de-aplicacoes-ricas-para-a-internet/#comments</comments>
		<pubDate>Fri, 16 Jan 2009 10:00:17 +0000</pubDate>
		<dc:creator>Klaus Peter Laube</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Desenvolvimento Web]]></category>
		<category><![CDATA[Gears]]></category>
		<category><![CDATA[Google App Engine]]></category>
		<category><![CDATA[RIA]]></category>

		<guid isPermaLink="false">http://www.profissionaisti.com.br/?p=566</guid>
		<description><![CDATA[Olá pessoal! Ontem me deparei com mais uma iniciativa da Google para o desenvolvimento rico para a internet, o Native Client. Este recurso nada mais é que um plugin que instala-se em seu navegador (Firefox 3) que permite rodar códigos nativos de máquina (x86) em uma aplicação web. Não captou a mensagem?! Poderemos ser capazes [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.profissionaisti.com.br/wp-content/uploads/2009/01/super-google.gif"><img class="alignleft size-medium wp-image-670" style="5px;" src="http://www.profissionaisti.com.br/wp-content/uploads/2009/01/super-google-285x300.gif" alt="" width="189" height="199" /></a></p>
<p>Olá pessoal!</p>
<p>Ontem me deparei com mais uma iniciativa da Google para o desenvolvimento rico para a internet, o <a title="Leia mais sobre o Native Client" href="http://code.google.com/p/nativeclient/" target="_blank">Native Client</a>. Este recurso nada mais é que um plugin que instala-se em seu navegador (Firefox 3) que permite <strong>rodar códigos nativos de máquina (x86) em uma aplicação web.</strong></p>
<p>Não captou a mensagem?! Poderemos ser capazes de executar códigos na máquina do usuário para privilegiar o processamento de informações, diminuindo a troca de informações desnecessárias entre cliente e servidor e utilizando (de forma inteligente) o processador do internauta. Exemplo: <a title="Instale o plugin e jogue Quake em seu navegador" href="http://nativeclient.googlecode.com/svn/trunk/nacl/googleclient/native_client/tests/quake/quake.html" target="_blank">jogue Quake no seu navegador</a>.</p>
<p>Obviamente é experimental e a Google afirma que não é seguro, mas você já reparou como a Google vem colaborando para um desenvolvimento rico para a internet?!</p>
<p><strong>SIMPLICIDADE / PADRÕES / LEGIBILIDADE</strong></p>
<p>Quando eu acessei o <a title="Buscador Google" href="http://www.google.com" target="_blank">buscador Google</a> pela primeira vez, automaticamente associei sua falta de &#8220;firulas&#8221; com falta de eficiência. Claro, essa imagem foi rapidamente apagada da minha mente e hoje além do buscador do Google, só conheço o buscador do <a title="Buscador Yahoo" href="http://br.yahoo.com/?p=us" target="_blank">Yahoo</a>.</p>
<p>Obviamente ele não foi o precursor, mas incentivou para uma internet mais limpa. Inclusive alguns clientes já chegaram para mim com a idéia: &#8220;quero um site objetivo como o do Google&#8221; e eu fico realmente feliz e aliviado com isso.</p>
<p>A Google não é conhecida por levar os padrões 100% à risca. Mas incentiva o uso através da indexação das páginas, favorecendo documentos semânticos, &#8220;forçando&#8221; os desenvolvedores a utilizarem corretamente os padrões e também a construir documentos &#8220;lógicamente legíveis&#8221; para favorecem seu &#8220;status&#8221; nos crawlers do buscador.</p>
<p><strong>ASSÍNCRONO/SERVIÇOS</strong></p>
<p>A primeira aplicação que faz um bom uso do AJAX que me vem à cabeça é o <a title="Seus e-mails no Google" href="http://www.gmail.com" target="_blank">Gmail</a>. Sinceramente, acho que AJAX é apropriado para aplicações web e não para websites. No começo disso tudo, eu era bem cético quando alguém vinha me falando que &#8220;usuário não está acostumado a não ver a página carregar&#8221; e afirmava que o sujeito que emitia um comentário desses era um completo ignorante. Ignorante era eu que não entendia a real situação da web em relação aos seus princípios.</p>
<p>No <a title="Visite o Google Code" href="http://code.google.com/intl/pt-BR/" target="_blank">Google Code</a> somos apresentados a uma série de <a title="Os serviços da Google em seu website" href="http://code.google.com/intl/pt-BR/apis/ajax/" target="_blank">API&#8217;s Ajax</a>, um <a title="Leia mais sobre o Google Web Toolkit" href="http://code.google.com/intl/pt-BR/webtoolkit/" target="_blank">web toolkit</a> de desenvolvimento AJAX em Java (<a title="Ninguém escapa da crise, nem a Google" href="http://www.profissionaisti.com.br/2009/01/a-crise-alcanca-a-gigante-google-anuncia-o-fechamento-de-seis-servicos-online/" target="_blank">que aparentemente não anda bem das pernas</a>) e também há alguns serviços prestados. Ah sim! os serviços Google&#8230; todo o desenvolvedor é agradecido ao Google pelo <a title="Leia mais sobre a API do Google Maps" href="http://code.google.com/intl/pt-BR/apis/maps/" target="_blank">Google Maps e sua API</a> e ao próprio Google Code por <a title="Hospede seus projetos no Google Code" href="http://code.google.com/intl/pt-BR/opensource/" target="_blank">hospedar projetos de Software Livre</a>. Você sabia que a Google já lançou mais de um <a title="Visite os projetos hospedados na Google" href="http://code.google.com/hosting/projects.html" target="_blank">milhão de linhas de código</a>?!</p>
<p><strong>DESENVOLVIMENTO</strong></p>
<p>Além das API&#8217;s que facilitam e muito a vida dos desenvolvedores, o Google investe bastante em desenvolvimento. Um exemplo é o <a title="Conheça o Google App. Engine" href="http://code.google.com/intl/pt-BR/appengine/" target="_blank">Google App Engine</a>, onde você é capaz de desenvolver aplicações para web de forma rápida e dentro da infra-estrutura da Google. Também temos o <a title="Saiba mais sobre o V8" href="http://code.google.com/intl/pt-BR/apis/v8/" target="_blank">V8</a>, o mecanismo de interpretação Javascript usado no Google Chrome.</p>
<p>Não podemos esquecer do <a title="Conheça o Google Gears" href="http://code.google.com/intl/pt-BR/apis/gears/" target="_blank">Google Gears</a>, onde você é capaz de executar aplicações web offline e ainda oferece maiores funcionalidades como Geolocation e API Desktop.</p>
<p>E por que não falar do <a title="Conheça o Android" href="http://code.google.com/intl/pt-BR/android/" target="_blank">Android</a>?! A primeira plataforma aberta para mobile que está sendo desenvolvida por mais de 30 empresas de tecnologia. A Google oferece <a title="Documentação do Android" href="http://code.google.com/intl/pt-BR/android/documentation.html" target="_blank">documentação completa</a> e <a title="Baixe o SDK" href="http://code.google.com/android/download.html" target="_blank">SDK</a> para desenvolver para a plataforma.</p>
<p>Ufa! E olha&#8230; que isso é só a ponta do Iceberg, nem falei de lançamentos espaciais, compras polêmicas, <a title="A crise atingiu a Google" href="http://www.profissionaisti.com.br/2009/01/a-crise-alcanca-a-gigante-google-anuncia-o-fechamento-de-seis-servicos-online/">crise financeira</a> e <a title="Leia mais sobre GoogleBomb! " href="http://www.profissionaisti.com.br/2008/12/google-bomb-um-paradoxo-sobre-a-criatura-e-o-criador/" target="_blank">teorias da conspiração</a>!</p>
<p>E você?! Conhece mais algum recurso da Google que favoreça o desenvolvimento para web?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.profissionaisti.com.br/2009/01/google-e-o-desenvolvimento-de-aplicacoes-ricas-para-a-internet/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Google Chrome está mais próximo do ambiente Linux</title>
		<link>http://www.profissionaisti.com.br/2009/01/google-chrome-esta-mais-proximo-do-ambiente-linux/</link>
		<comments>http://www.profissionaisti.com.br/2009/01/google-chrome-esta-mais-proximo-do-ambiente-linux/#comments</comments>
		<pubDate>Tue, 13 Jan 2009 14:00:13 +0000</pubDate>
		<dc:creator>Klaus Peter Laube</dc:creator>
				<category><![CDATA[Google]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[Desenvolvimento Web]]></category>
		<category><![CDATA[Google Chrome]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[navegadores]]></category>

		<guid isPermaLink="false">http://www.profissionaisti.com.br/?p=604</guid>
		<description><![CDATA[Com a expectativa de lançamento da versão 2.0 do Google Chrome, chega também a &#8220;esperança&#8221; do lançamento do navegador para os sistemas Mac e Linux. Quando o Chrome apareceu, fiz questão de instalar uma máquina virtual e ver como era esse novo filho da poderosa Google. Me surpreendí como todo mundo, e me apeguei muito [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_622" class="wp-caption alignleft" style="width: 156px"><a href="http://www.profissionaisti.com.br/wp-content/uploads/2009/01/google-chrome.jpg"><img class="size-medium wp-image-622" src="http://www.profissionaisti.com.br/wp-content/uploads/2009/01/google-chrome.jpg" alt="Logotipo Google Chrome" width="146" height="146" /></a><p class="wp-caption-text">Logotipo Google Chrome</p></div>
<p>Com a expectativa de <a title="Leia mais no BR-Linux" href="http://br-linux.org/2009/as-novidades-do-google-chrome-20/" target="_blank">lançamento da versão 2.0 do Google Chrome</a>, chega também a &#8220;esperança&#8221; do lançamento do navegador para os sistemas Mac e Linux.</p>
<p>Quando o <a title="Saiba mais sobre o Google Chrome" href="http://www.google.com/chrome" target="_blank">Chrome</a> apareceu, fiz questão de instalar uma <a title="Saiba mais sobre o VirtualBox" href="http://www.virtualbox.org/" target="_blank">máquina virtual</a> e ver como era esse novo filho da poderosa Google. Me surpreendí como todo mundo, e me apeguei muito ao navegador. Isso pelo fato de usar o mesmo motor de outro navegador que gosto muito, o <a title="Saiba mais sobre o Safari" href="http://www.apple.com/safari/" target="_blank">Safari</a>. Também por focar na interpretação do Javascript, incentivando um desenvolvimento mais padronizado com a utilização do ECMAScript, em vez de variantes proprietárias.</p>
<p>Mas enquanto a Google não lança oficialmente o Chrome para Linux/Mac, o grupo Code Weavers portou (já faz um tempo) o navegador utilizando o <a title="Leia mais sobre o Wine no Wikipedia" href="http://pt.wikipedia.org/wiki/Wine" target="_blank">Wine</a>. Você pode conferir o resultado na página oficial do <a title="Use Chrome no Linux e Mac" href="http://www.codeweavers.com/services/ports/chromium/" target="_blank">CrossOver Chromium</a>, mas ainda prefiro utilizar uma máquina virtual rodando Windows ou esperar que enfim a Google nos presenteie com este fascinante navegador.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.profissionaisti.com.br/2009/01/google-chrome-esta-mais-proximo-do-ambiente-linux/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Pela primeira vez desde 1999 o IE6 fica abaixo dos 69% de mercado</title>
		<link>http://www.profissionaisti.com.br/2009/01/pela-primeira-vez-desde-1999-o-ie6-fica-abaixo-dos-69-de-mercado/</link>
		<comments>http://www.profissionaisti.com.br/2009/01/pela-primeira-vez-desde-1999-o-ie6-fica-abaixo-dos-69-de-mercado/#comments</comments>
		<pubDate>Mon, 12 Jan 2009 10:27:00 +0000</pubDate>
		<dc:creator>Klaus Peter Laube</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[Desenvolvimento Web]]></category>
		<category><![CDATA[navegadores]]></category>

		<guid isPermaLink="false">http://www.profissionaisti.com.br/?p=589</guid>
		<description><![CDATA[Sim! Estamos rumando para o caminho certo, e o IE6 está começando a perder seu reinado. A fonte da notícia é o Br-Linux.org que também nos delicia com a notícia de que o Firefox tomou 21% da fatia. Demais navegadores (Safari e Chrome) cresceram, e o Opera (o melhor navegador que ninguém usa) continua abaixo [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.profissionaisti.com.br/wp-content/uploads/2009/01/firefox-condom.jpg"><img class="alignleft size-medium wp-image-590" style="10px 5px;" src="http://www.profissionaisti.com.br/wp-content/uploads/2009/01/firefox-condom-300x256.jpg" alt="" width="145" height="124" /></a>Sim! Estamos rumando para o caminho certo, e o IE6 está começando a <a title="Vamos acabar com o IE6 urgente!" href="http://www.profissionaisti.com.br/2009/01/vamos-acabar-com-o-ie6-urgente/">perder seu reinado</a>.</p>
<p>A fonte da notícia é o <a title="Leia mais no BrLinux" href="http://br-linux.org/2009/firefox-passa-dos-21-ie-abaixo-dos-69-do-mercado-pela-primeira-vez-desde-1999/" target="_blank">Br-Linux.org</a> que também nos delicia com a notícia de que o Firefox tomou 21% da fatia. Demais navegadores (Safari e Chrome) cresceram, e o Opera (<a title="Leia mais sobre o Opera" href="http://tecnologia.uol.com.br/ultnot/2008/11/17/ult4213u594.jhtm" target="_blank">o melhor navegador que ninguém usa</a>) continua abaixo do 1% de uso.</p>
<p>Esta é sem dúvida uma notícia muito agradável para os desenvolvedores web&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.profissionaisti.com.br/2009/01/pela-primeira-vez-desde-1999-o-ie6-fica-abaixo-dos-69-de-mercado/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>SVG x Canvas: Entenda as diferenças</title>
		<link>http://www.profissionaisti.com.br/2009/01/svg-x-canvas-entenda-as-diferencas/</link>
		<comments>http://www.profissionaisti.com.br/2009/01/svg-x-canvas-entenda-as-diferencas/#comments</comments>
		<pubDate>Fri, 09 Jan 2009 17:02:49 +0000</pubDate>
		<dc:creator>Klaus Peter Laube</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[Desenvolvimento Web]]></category>
		<category><![CDATA[HTML 5]]></category>
		<category><![CDATA[RIA]]></category>
		<category><![CDATA[SVG]]></category>

		<guid isPermaLink="false">http://www.profissionaisti.com.br/?p=569</guid>
		<description><![CDATA[Olá pessoal! Estou desenvolvendo um projeto de iniciação científica onde o objetivo está em desenvolver uma aplicação de estatísticas empresariais, em RIA, livre, totalmente padronizada, e que atinja níveis de interação com os gráficos equivalentes a uma aplicação desenvolvida em Adobe Flash. Pesquisando sobre as possibilidades não precisei garimpar muito, já que na página do [...]]]></description>
			<content:encoded><![CDATA[<p>Olá pessoal!</p>
<div id="attachment_573" class="wp-caption alignleft" style="width: 160px"><a href="http://www.profissionaisti.com.br/wp-content/uploads/2009/01/inkscape-044-outlineviewpreview.png"><img class="size-thumbnail wp-image-573" src="http://www.profissionaisti.com.br/wp-content/uploads/2009/01/inkscape-044-outlineviewpreview-150x150.png" alt="SVG com Inkscape" width="150" height="150" /></a><p class="wp-caption-text">SVG com Inkscape</p></div>
<p>Estou desenvolvendo um projeto de iniciação científica onde o objetivo está em desenvolver uma aplicação de estatísticas empresariais, em <a title="Leia sobre RIA no Wikipedia" href="http://pt.wikipedia.org/wiki/RIA" target="_blank">RIA</a>, livre, totalmente padronizada, e que atinja níveis de interação com os gráficos equivalentes a uma aplicação desenvolvida em <a title="Leia mais sobre Flash no Wikipedia" href="http://www.google.com.br/url?sa=t&amp;source=web&amp;ct=res&amp;cd=8&amp;url=http%3A%2F%2Fpt.wikipedia.org%2Fwiki%2FAdobe_Flash&amp;ei=nnJnSZDvL4ym8QSn-ezCBw&amp;usg=AFQjCNFbjTJwFbHGLn43XYw470W7-5dNOQ&amp;sig2=nv9bRI4bsVwOUQNBKcJZ5g" target="_blank">Adobe Flash</a>.</p>
<p>Pesquisando sobre as possibilidades não precisei garimpar muito, já que na página do próprio <a title="Tutoriais de desenvolvimento web" href="http://w3schools.com/" target="_blank">W3C Schools</a> nos deparamos com o <a title="Saiba mais sobre o SVG no W3Schools" href="http://w3schools.com/svg/default.asp" target="_blank">SVG</a>.</p>
<p><strong>SVG &#8211; Scalable Vector Graphics</strong></p>
<p>O <em>Scalable Vector Graphics</em> é um padrão do W3C para gráficos vetoriais para a web baseado em XML. Vem sendo utilizado por editores vetoriais de renome, e inclusive o editor aberto Inkscape adota o SVG como formato nativo.</p>
<p>A maioria dos navegadores do mercado (<a title="Vamos acabar com o IE6 urgente!" href="http://www.profissionaisti.com.br/2009/01/vamos-acabar-com-o-ie6-urgente/">há algumas excessões</a>) são capazes de reproduzir SVG. E inclusive, há padrões específicos para renderizações em dispositivos móveis. E ainda, pode-se manusear sua estrutura através do DOM e tornar as imagens SVG animadas através de um pouco de Javascript.</p>
<p>Para entender melhor o SVG, você pode dar uma olhada no <a title="Leia mais sobre SVG no Mozilla Developer Center" href="https://developer.mozilla.org/en/SVG" target="_blank">Mozilla Developer Center</a> e ver alguns <a title="Jogue Tetris sem Flash nem Java!" href="http://www.croczilla.com/svg/samples/svgtetris/svgtetris.svg" target="_blank">exemplos incríveis de SVG</a>.</p>
<p>Pesquisando mais sobre o assunto, no <a title="Conheça o Opera Developer Community" href="http://dev.opera.com/" target="_blank">Opera Developer Community</a> me deparei com um outro recurso que até então nunca tinha ouvido falar, o elemento <a title="Saiba mais sobre o elemento Canvas" href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html" target="_blank">Canvas</a>.</p>
<p><strong>CANVAS</strong></p>
<p>O elemento Canvas é uma das novidades presentes nas <a title="Saiba mais sobre a HTML 5" href="http://www.whatwg.org/specs/web-apps/current-work/multipage/" target="_blank">especificações da HTML 5</a>.</p>
<p>Os bons navegadores já possuem suporte a algumas recomendações da HTML 5, inclusive este recurso foi primeiramente implementado pelo Safari. No Mozilla Developer Center somos apresentados a alguns <a title="Aprenda sobre Canvas" href="https://developer.mozilla.org/en/Canvas_tutorial" target="_blank">tutoriais de Canvas</a> e <a title="Exemplo de interação com elemento Canvas" href="https://developer.mozilla.org/samples/raycaster/RayCaster.html">exemplos de interações com Javascript</a>.</p>
<p>Admito que não sei muito sobre este, por isso decidí procurar alguém que fizesse um comparativo entre os dois (SVG e Canvas) para poder entender qual o &#8220;campo de ação&#8221; de ambos.</p>
<p><strong>SCALABLE VECTOR GRAPHICS X CANVAS ELEMENT</strong></p>
<p>Foi aí que encontrei este <a title="SVG X Canvas" href="http://people.mozilla.com/~vladimir/xtech2006/" target="_self">incrível conteúdo</a>, criado por Vladimir Vuki?evi?, que faz uma comparação amistosa entre eles e apresenta suas principais vantagens.</p>
<p><strong>CONSIDERAÇÕES FINAIS</strong></p>
<p><span style="underline;"><em>Na minha opinião</em></span>, vou continuar meu projeto focando o SVG. Isso devido ao fato de optar pelo desenvolvimento com xHTML e também de que SVG é um formato e não um recurso puramente da HTML.</p>
<p>Serei capaz de construir &#8220;templates&#8221; dos gráficos com o Inkscape e permitir que a aplicação o &#8220;alimente&#8221; através de serializações XML.</p>
<div id="attachment_574" class="wp-caption alignright" style="width: 267px"><a href="https://developer.mozilla.org/En/MSX_Emulator_(jsMSX)" target="_blank"><img class="size-full wp-image-574" src="http://www.profissionaisti.com.br/wp-content/uploads/2009/01/jsmsx_canvas.png" alt="Emulador de MSX com Javascript e Canvas" width="257" height="196" /></a><p class="wp-caption-text">Emulador de MSX com Javascript e Canvas</p></div>
<p>Não desmerecendo o Canvas, que é sem dúvida mais simples, rico e prático de construir e interagir que o SVG. As imagens apresentadas no documento do Vladimir e nos portais de desenvolvimento do Mozilla e do Opera deixam qualquer um de &#8220;queixo caído&#8221;. Com certeza se o foco da aplicação fosse outro, optaria pelo Canvas.</p>
<p>Independente da minha ou da sua preferência, é bom saber que a Web está caminhando para um universo rico sem se desprender de seus padrões.</p>
<p>Até a próxima&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.profissionaisti.com.br/2009/01/svg-x-canvas-entenda-as-diferencas/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Conheça a Mootools: Framework Javascript orientada a objetos</title>
		<link>http://www.profissionaisti.com.br/2009/01/conheca-a-mootools-framework-javascript-orientada-a-objetos/</link>
		<comments>http://www.profissionaisti.com.br/2009/01/conheca-a-mootools-framework-javascript-orientada-a-objetos/#comments</comments>
		<pubDate>Thu, 08 Jan 2009 10:00:39 +0000</pubDate>
		<dc:creator>Klaus Peter Laube</dc:creator>
				<category><![CDATA[Geral]]></category>
		<category><![CDATA[Desenvolvimento Web]]></category>
		<category><![CDATA[mootools]]></category>

		<guid isPermaLink="false">http://www.profissionaisti.com.br/?p=406</guid>
		<description><![CDATA[Olá galera&#8230; Como continuação do post sobre desenvolvimento web com software livre (onde mencionei que iria detalhar mais sobre as ferramentas utilizadas), irei falar hoje um pouco sobre a Mootools. A Mootools é uma framework Javascript compacta, modular, orientada a objetos e open source (MIT) que vem ganhando muitos adeptos devido ao seu uso por [...]]]></description>
			<content:encoded><![CDATA[<p>Olá galera&#8230;</p>
<p>Como continuação do post sobre <a title="Saiba mais sobre Desenvolvimento Web com Software Livre" href="http://www.profissionaisti.com.br/2008/12/desenvolvimento-web-com-software-livre/">desenvolvimento web com software livre</a> (onde mencionei que iria detalhar mais sobre as ferramentas utilizadas), irei falar hoje um pouco sobre a <a title="Página oficial da Mootools" href="http://www.mootools.net" target="_blank">Mootools</a>.</p>
<p><img class="alignleft" style="5px;" src="http://www.mootools.net/assets/images/mootools.png" alt="" width="184" height="46" />A Mootools é uma framework Javascript compacta, modular, orientada a objetos e open source (<a title="Saiba mais sobre a licença" href="http://pt.wikipedia.org/wiki/Licen%C3%A7a_MIT" target="_blank">MIT</a>) que vem ganhando muitos adeptos devido ao seu uso por nomes conhecidos na web, como o <a title="Validador W3C" href="http://validator.w3.org/" target="_blank">W3C</a>, <a title="A Mootools é utilizada no CMS Joomla!" href="http://joomla.org/" target="_blank">Joomla!</a>, <a title="Página oficial do SO Ubuntu Linux" href="http://ubuntu.com/" target="_blank">Ubuntu</a>, <a title="Portal Cnet" href="http://cnet.com/" target="_blank">Cnet</a>, etc.</p>
<p>Particularmente gosto muito do jeito como se programa em Mootools. Ao contrário da <a title="Leia os posts do Profissionais TI sobre JQuery" href="http://www.profissionaisti.com.br/tag/jquery/">JQuery</a> (outra excepcional framework), a Mootools é mais &#8220;explícita&#8221;, mais abrangente e consequentemente mais complexa em relação a JQuery, mas isso se dá ao fato de que &#8220;<a title="Leia mais no Tableless.com.br" href="http://www.tableless.com.br/jquery-e-bom-para-designers" target="_blank">JQuery é boa para designers</a>&#8221; e &#8220;<a title="Leia um comparativo no Mootorial.com" href="http://www.mootorial.com/wiki/mootorial/00a-mootoolsvsothers" target="_blank">Mootools é boa para programadores</a>&#8220;.</p>
<p><strong>SELETORES/DOM/EVENTOS</strong></p>
<p>O esquema de seleção de elementos da Mootools é bem interessante. Para selecionarmos um elemento pelo seu ID podemos utilizar simplesmente o <strong>$ </strong>(cifrão), já quando queremos construir um seletor mais complexo utilizamos <strong>$$ </strong>(dois cifrões).</p>
<p>Ex.:</p>
<p style="30px;">$(&#8216;botao-alerta&#8217;).addEvent(&#8216;click&#8217;, function()<br />
{<br />
alert(&#8216;Emitindo um alerta!&#8217;);<br />
});</p>
<p>$$(&#8216;input[type="button"]&#8216;).addEvent(&#8216;click&#8217;, function()<br />
{<br />
alert(&#8216;Emitindo outro alerta!&#8217;);<br />
});</p>
<p>O exemplo acima atribui duas chamadas ao evento &#8220;onclick&#8221; de um elemento do tipo &#8220;button&#8221;. A diferença é que a primeira atribui somente ao elemento com o ID &#8220;botao-alerta&#8221;, já a segunda atribui a qualquer &#8220;input&#8221; que seja do tipo &#8220;button&#8221;.</p>
<p><strong>AJAX/JSON</strong></p>
<p>Essas duas sopas de letrinhas caíram como uma bomba no mundo do desenvolvimento web. O primeiro (AJAX &#8211; Assynchronous Javascript and XML) é o responsável pelas requisições assíncronas (&#8220;invisíveis&#8221;) que presenciamos nas mais diversas aplicações ricas para a internet. O segundo complementa o Ajax (JSON &#8211; Javascript Object Notation) fazendo com que sejamos capazes de manusear os valores de resposta de um Ajax puramente por variáveis Javascript.</p>
<p>A Mootools possui um excelente suporte a esses caras. Seus métodos de trabalho com Ajax podem parecer complicados no início, mas são bem amigáveis e eficazes.</p>
<p><strong>EFEITOS/ANIMAÇÕES</strong></p>
<p>A grande magia para a maioria dos desenvolvedores Javascript está na facilidade com que a Mootools proporciona os recursos de animação de elementos.</p>
<p>Em seu <a title="Core Builder da Mootools" href="http://www.mootools.net/core" target="_blank">core</a> possuímos excelentes recursos para efeitos e animações que interagem diretamente na CSS de cada elemento. E ainda, há <a title="More Builder da Mootools" href="http://www.mootools.net/more" target="_blank">plugins de efeitos para download</a>, como <strong>slider</strong>, <strong>drag and drop</strong>, <strong>sortables</strong>, <strong>accordion</strong>, etc.</p>
<p>Nesse quesito a Mootools é um prato cheio para os criativos.E ainda contamos com um projeto chamado <a title="Veja a MochaUI em ação" href="http://mochaui.com/demo/" target="_blank">MochaUI</a>, uma biblioteca de interface totalmente baseada na Mootools, semelhante a <a title="Conheça a EXTJs" href="http://extjs.com/" target="_blank">EXTjs</a> e <a title="Conheça a JQuery UI" href="http://ui.jquery.com/" target="_blank">JQuery UI</a>.</p>
<p>Flash para quê?</p>
<p><strong>CURVA DE APRENDIZAGEM</strong></p>
<p>A primeira vista a Mootools pode parecer complexa. Em relação a outras <a href="http://www.profissionaisti.com.br/2008/12/frameworks-e-a-ti/" target="_blank">frameworks</a>, que você executa uma chamada e os elementos do seu HTML saem saltitando pela tela, a Mootools requer um pouco mais de tempo e linhas de implementação.</p>
<p>Isso pode chatear muitos desenvolvedores, principalmente os que já conhecem a <a title="Leia os posts do Profissionais TI sobre JQuery" href="http://www.profissionaisti.com.br/tag/jquery/">JQuery</a> e <a title="Leia mais no Clientside.com.br" href="http://clientside.com.br/eu-me-rendo-jquery-e-legal-para-caramba-mesmo/" target="_blank">sabem que ela é extremamente fácil porém poderosa</a>. Embora possa agradar muitos outros, que como eu, não gostam desse sentimento de &#8220;magia negra&#8221; que fica no ar quando as coisas são implícitas demais.</p>
<p><strong>CONSIDERAÇÕES FINAIS<br />
</strong></p>
<p>Bom, espero ter atiçado a curiosidade de muitos em relação a esta excelente <a href="http://www.profissionaisti.com.br/2008/12/frameworks-e-a-ti/" target="_blank">framework</a>, e inclusive ter incentivado que pesquisem sobre outras tantas que existem por aí (<a title="Leia os posts do Profissionais TI sobre JQuery" href="http://www.profissionaisti.com.br/tag/jquery/">JQuery</a>, Dojo, Mochikit, Prototype, etc.), pois elas incentivam um desenvolvimento livre, leve, rico e padronizado.</p>
<p>Até a próxima&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.profissionaisti.com.br/2009/01/conheca-a-mootools-framework-javascript-orientada-a-objetos/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Menu fácil fácil com jQuery e CSS</title>
		<link>http://www.profissionaisti.com.br/2008/11/menu-facil-facil-com-jquery-e-css/</link>
		<comments>http://www.profissionaisti.com.br/2008/11/menu-facil-facil-com-jquery-e-css/#comments</comments>
		<pubDate>Mon, 10 Nov 2008 02:34:48 +0000</pubDate>
		<dc:creator>Jackson Caset</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[JQuery]]></category>
		<category><![CDATA[Desenvolvimento Web]]></category>

		<guid isPermaLink="false">http://www.profissionaisti.com.br/?p=129</guid>
		<description><![CDATA[Ola pessoal! Bom, fim de final de semana, daqui a pouco começa o primeiro dia de cão da semana, a Segunda-feira. Como ultimamente venho trabalhando muito com jQuery, ja criei vários plugins (conheça as melhorias feitas na jQuery UI Dialog) que me ajudam bastante na hora de desenvolver, porém, nunca tive tempo hábil para postar [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Ola pessoal!</p>
<p style="text-align: justify;">Bom, fim de final de semana, daqui a pouco começa o primeiro dia de cão da semana, a Segunda-feira.</p>
<p style="text-align: justify;">Como ultimamente venho trabalhando muito com <a href="http://www.jquery.com" target="_blank">jQuery</a>, ja criei vários plugins (<a href="http://www.profissionaisti.com.br/2008/11/jquery-dialog-melhorias-interessantes/" target="_blank">conheça as melhorias feitas na jQuery UI Dialog</a>) que me ajudam bastante na hora de desenvolver, porém, nunca tive tempo hábil para postar os mesmos para amigos, alunos e até mesmo para a comunidade web. Hoje com um pouco mais de tempo (tempo???) estarei postando mais um dos &#8220;plugins&#8221;.</p>
<p style="text-align: justify;">Quando quebrei a cabeça, no início do ano, não havia nada em <a href="http://www.jquery.com" target="_blank">jQuery</a> que fosse realmente simples. Hoje ja pode existir, mas não fui atrás para saber (se alguém souber de algo, avisem <img src='http://www.profissionaisti.com.br/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ).</p>
<p style="text-align: justify;">Depois de algumas horas e alguns cafés, saiu o que eu queria. Criei menus encadeados com ul e li e, após aplicação de algumas linhas de javascript, lá estava meu menu com vários níveis de submenus.</p>
<p style="text-align: justify;">Vejam o resultado em: <a href="http://www.profissionaisti.com.br/jquery/menu" target="_blank">http://www.profissionaisti.com.br/jquery/menu</a><br />
<a href="http://www.profissionaisti.com.br/jquery/menu.zip" target="_blank">Baixe os arquivos aqui/Download files here.</a></p>
<p style="text-align: justify;">
<p style="text-align: justify;">Se puderem contribuir com melhorias, mandem seus comentários. Alterem cores, bordas, margens e etc como ficar melhor em seus projetos.</p>
<p style="text-align: justify;"><span style="text-decoration: underline;"><strong>Testado em: IE6, IE7, FF2.x, FF3, GChrome<br />
</strong></span></p>
<p style="text-align: justify;">Grande abraço!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.profissionaisti.com.br/2008/11/menu-facil-facil-com-jquery-e-css/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
	</channel>
</rss>

