The 500 Blog - Homepage
Em Novembro surgiu um desafio no P@P para criar um blog em 500 linhas. O objectivo não era fácil (tanto eu como o outro participante falhámos, de largo), mas, pelo menos, ficou montado um motor próprio para aprendizagem, com muitos exemplos do que devem ser boas práticas de programação em PHP. O projecto está no GitHub, em duas branches: a master e a compact, que é igual à outra, mas sem comentários, sem linhas em branco, instruções inline onde é possível, etc. O que se segue é a tradução adaptada do README que acompanha o projecto.

0. Conteúdos

  1. Aviso
  2. O desafio
  3. Instalação
  4. Ficheiros onde é necessário mexer
  5. Notas avulsas

1. Aviso

Isto não é próprio para ambientes de produção. Não posso enfatizar isto o suficiente.

Não foi testado em profundidade, a performance não foi medida, nem sequer foi testado para ataques menos comuns.

É uma prova de conceito com fins educativos e nada mais do que isso. Se o que precisas é apenas de um motor de blog, usa o Wordpress ou semelhante. Se queres mesmo fazer o teu motor de blog, ao menos usa uma framework madura, como a Yii, Kohana, CakePHP ou o que mais te der jeito.

Se quiseres mesmo, mesmo, mesmo usar este projecto, ficas avisado. Simplesmente respeita a licença.

2. O desafio

Tudo começou quando um programador principiante pediu ajuda para fazer um blog, neste post no Portugal-a-Programar (P@P). A primeira (e segunda) resposta foi, tal como era de prever, uma sugestão para usar Wordpress (pelo próprio administrador do P@P).

Claro que começou uma pequena guerra. Afinal, é um fórum de programação, e um pouco mais de ajuda talvez fosse indicado. No entanto, o autor do tópico já tinha andado a empestar o fórum com perguntas sem sentido, demonstrando uma total falta de ética de trabalho e até de capacidades de pesquisas simples no Google.

As terceira e quarta respostas iniciaram o desafio: primeiro, o taviroquai respondeu que "mesmo um simples blog daria cerca de 50 linhas de código mas pelo menos a pessoa aprendia algo", a que o admin jpaulino retorquiu "então força, explica como se faz um blog em 50 linhas; se conseguirem em menos de 500 (10x mais do que disseste), pago-te um copo".

O taviroquai realmente apresentou um "blog" (notem as aspas) em menos de 50 linhas. Tinha posts. Ponto. Nada de utilizadores. Nada de categorias. Nada de comentários. Apenas uma página de administração e uma página principal interminável. E ainda usou um motor ORM externo.

Batoteiro. :p

Então propus as regras do desafio (neste post, o administrador partiu os tópicos depois da guerra de palavras):

  1. Não usar bibliotecas externas;
  2. Zona de administração;
  3. Suporte para categorias e/ou tags;
  4. Suporte para comentários (mas não necessariamente administrá-los);
  5. Todo o HTML conta para o limite das 500 linhas;
  6. CSS e JavaScript não contam;
  7. Várias instruções na mesma linha são proibidas, excepto em concatenação de strings, instruções de controlo de fluxo com apenas uma instrução dentro do bloco e outras situações similares;
  8. O HTML deverá estar devidamente formatado e identado (excepção feita a apenas um elemento dentro de outro).

Primeiro, disse que o limite deveria ser curto se fossem seguidas boas práticas. Quando comecei (seguindo boas práticas), revi a minha posição para "talvez caiba". Ao aproximar-me da conclusão, novamente pensei que não chegasse; e não chegou. Bati nas 1127 linhas.

3. Instalação

A estrutura de dados está no ficheiro 500blog.sql. É só importá-la para uma base de dados MySQL. Os dados de acesso à mesma devem ser alterados no ficheiro core/PDOSingleton.class.php.

O blog só funcionará com o ficheiro .htaccess fornecido. Eu queria mesmo endereços que fossem amigáveis para humanos (e para SEO), daí a necessidade das regras constantes nesse ficheiro.

Também incluí um favicon, porque os browsers tentam sempre puxá-lo, e isso colocava mais um request à aplicação. Se o ficheiro existir, é servido pelo próprio web server e alivia um pouco a carga.

Apesar da estrutura de ficheiros que usei durante o desenvolvimento seja a que se vê, aconselho veementemente a colocarem os directórios controllers, core, models e views fora do document root e, se possível, a removerem as permissões de escrita. Isto irá reforçar a segurança, porque a funcionalidade de autoloading vai tentar carregar qualquer coisa que tenha o formato de nome correcto nesses directórios. Se um utilizador mal intencionado conseguir enfiar lá alguma coisa, estás ferrado (se bem que, se ele já ganhou acesso ao sistema de ficheiros, estás ferrado de qualquer maneira).

4. Ficheiros onde é necessário mexer

No index.php, só é preciso ajustar o caminho para a classe App (se seguiram o meu conselho anterior).

Em core/App.class.php é preciso ajustar os caminhos na instrução set_include_path do construtor (novamente, se seguiram o meu conselho anterior).

Em core/PDOSingleton.class.php, como já disse acima, tem que se ajustar os dados de acesso à base de dados.

E é basicamente isto. Neste momento, terás um blog perfeitamente funcional.

5. Notas avulsas

Os ficheiros em views/default são as partes externas do resto das views. Contêm o cabeçalho e, no frontend, a barra lateral.

As classes do core estão razoavelmente comentadas, mas faço aqui um apanhado rápido:

App

Isto serve tanto como router dos requests como gestor de configurações. Pode ser bastante melhorado em ambos os aspectos, mas especialmente ao nível da gestão de configurações (por exemplo, os dados de acesso à base de dados poderiam estar aqui).

Formen

Isto é um motor ORM muito simples. Tem como características lazy loading, carregamento de modelos relacionados (isto é, usando um objecto do modelo Post, pode-se chamar directamente os comentários, ele "sabe" que comentários pertencem ao post actual), updates selectivos, atribuição em massa segura, suporte a paginador e outras pequenas pérolas.

Para o tempo que demorou a implementar (pouco), estou bastante satisfeito com o conjunto de características. No entanto, não está nem sequer perto de uma ORM completa, à semelhança das que se encontram em frameworks maduras (já mencionei que não se deve reinventar a roda como eu fiz com este projecto?).

As várias funcionalidades foram implementadas iterativamente, às vezes com alguns dias de intervalo, e posso ter descurado comentários nalgumas secções de código mais obscuras. Se alguma coisa não estiver inteiramente clara, estejam à vontade para me dizer qualquer coisa.

ModelMultiFactory

Esta classe implementa o paradigma factory para vários objectos do mesmo modelo. Não é para ser instanciada directamente, mas sim devolvida por alguns métodos da classe Formen. Oferece a maioria da funcionalidade dos arrays nativos do PHP (pode-se fazer foreach pelos itens), excepto is_array (porque, de facto, não é um array).

PDOSingleton

Classe bastante simples, um singleton que retorna uma conexão PDO.

Paginator

Mais uma vez, uma classe muito simples que ajuda com a paginação dos items (tanto na construção do paginador em si, como para limitar as queries).

WebUser

Provavelmente, isto foi a coisa mais estúpida que eu fiz em relação ao desafio. É uma classe para gerir sessões de utilizadores, não usando o sistema de sessões nativo. Apesar de ser correcto, de um ponto de vista de arquitectura aplicacional, é um carregamento de linhas, só para gerir as sessões segundo as melhores práticas.

Se tivesse usado a gestão de sessões nativa, tinha poupado imensas linhas. Afinal, quantas aplicações web andam para aí assim? Na minha perseguição pelas melhores práticas, só com esta classe, acabei por dar um tiro no pé e ultrapassar de largo o limite do desafio.

Não tem JavaScript absolutamente nenhum. No entanto, é bastante simples de integrar, por exemplo, o editor TinyMCE. É só aplicá-lo à textarea na zona de administração dos posts para ganharmos logo imenso em funcionalidade (lembrete: o JavaScript não contava para o desafio).

O CSS foi feito usando SASS e Compass. Eu forneço a folha de estilos "compilada", os ficheiros SCSS originais e até o ficheiro de configuração Ruby do Compass. Novamente, lembrem-se que o CSS não contava para o limite do desafio.

Todavia, faltam alguns estilos. Por exemplo, os posts fixos (sticky) no front-end não são diferentes dos normais – e deviam. A classe até está lá, é só ajustar o estilo.

Todo o sistema não usa imagens. A única imagem no directório correspondente é uma grelha criada pelo Compass, que não é usada. Tudo o resto é puro CSS.

O resto dos ficheiros devem ser bastante claros. Se algo não o for, alertem-me.

Se quiserem fazer algo real disto, digam-me; vou-me divertir imenso só por saber que alguém conseguiu transformar esta prova de conceito nalguma coisa decente.

Página de login da zona de administração Página principal da zona de administração Página de listagem de posts na zona de administração Página de administração de um post Página de administração de comentários - notem como não é possível alterá-los Listagem de posts de uma categoria específica Visualização de um post, com comentários

Partilhar no Sapo Links Partilhar no del.icio.us Partilhar no Digg Partilhar no Twitter Partilhar no StumbleUpon Partilhar no MySpace Partilhar no Facebook

Comentários Deixar um comentário

Tem que efectuar login para poder deixar comentários!

Se não está registado, registe-se aqui.
 Doar (via PayPal)
 Categorias
 Arquivo
 Projectos em Destaque
 Últimas Postas no Blog
 Últimos Comentários do Blog