Partilhar campos entre os formulários de criação e edição em Laravel

Esta é simples.

Nas tuas aplicações, é provável que tenhas recursos que são criados e editados com formulários. Os formulários de criação e edição são basicamente os mesmos (com os campos a serem exactamente iguais), mas funcionam de uma maneira ligeiramente diferente.

Na vista de criação começas com um formulário vazio, enquanto que na vista de edição começas com o formulário preenchido com os dados actuais. Mas, em ambas as vistas, queres o conteúdo introduzido anteriormente, no caso de a validação falhar e sere redireccionado para o formulário.

Portanto, se quiseres escrever os campos apenas uma vez e depois incluí-los em ambas as vistas, essa é uma maneira relativamente limpa de o fazer:

Se o campo indicado no primeiro parâmetro não estiver definido, a função auxiliar old () devolve  null ou o valor passado como o segundo parâmetro. Usando uma expressão com o null coalescing operator como segundo parâmetro dá-nos a capacidade de continuar a devolver null se nenhum dos valores anteriores estiver definido.

Isto funciona como esperado em ambas as vistas. Na vista de criação, o $user->email não estaria definido e null seria devolvido (e o campo ficaria vazio), na vista de edição $user->e-mail estaria definido e seria devolvido. Excepto se existir conteúdo submetido e que falhou na validação, nesse caso esse conteúdo é devolvido (em ambas as vistas).

Também pode ser escrito desta maneira, com o mesmo resultado:

Laravel Elixir e Zurb Foundation, revisitado

Editado a 25 de Novembro de 2016: Vê o fundo do post para uma actualização relativa ao Elixir 6.

Na última vez que escrevi sobre como usar a framework Foundation com o Laravel Elixir disse que o pacote npm não instalava as dependências necessárias e, por isso, tínhamos que instalar via Bower. Não tenho certeza se era eu que estava errado ou se alguma coisa mudou depois desse post, mas agora isso já não é assim.

Além disso, entretanto, saiu uma nova versão da framework, Foundation for Sites 6. Logo, acho que é boa ideia reescrever o tutorial sobre como substituir o Bootstrap pela Foundation no Laravel Elixir.

0. Configurar

Antes de começar, certifica-te de que tens o Node.js, npm e gulp instalados e a funcionar. Na raiz do projeto, deves ser capaz de executar os comandos npm install e gulp sem erros.

Vê na documentação do Laravel Elixir mais informações.

1. Instalar a Foundation

1.1. Se ainda não o fizeste, instala as dependências do npm. Antes de executar o comando a seguir deves querer remover a linha do bootstrap-sass do ficheiro package.json, para que o Bootstrap não seja instalado

1.2. Se o Bootstrap já estiver instalado podes removê-lo com o seguinte comando.

1.3. Instala a framework Foundation.

1.4. (opcional) A Foundation 6 traz o Motion UI, uma biblioteca Sass para criar animações e transições. Instala-a com o seguinte comando.

Se não a quiseres usar, remove qualquer referência a ela nos ficheiros seguintes.

2. Criar os ficheiros sass

Agora, vais precisar de dois ficheiros, normalmente na directoria “resources/assets/sass”. Estes são os ficheiros que, posteriormente, vais editar.

2.1. Copia o ficheiro  “_settings.scss” da directoria “node_modules/foundation-sites/scss/settings” para a directoria “resources/assets/sass”. Este ficheiro contém todos os parâmetros dos vários componentes da Foundation que podemos personalizar.

2.2. Em “resources/assets/sass” cria um ficheiro chamado “app.scss” com o seguinte conteúdo. Este é o ficheiro principal, em que se fazem todos os imports / includes e escreves o teu próprio sass.

Aqui, aconselho a comentar todos os includes e apenas descomentar os que precisas e à medida que vão sendo precisos (de notar que o foundation-global-styles é basicamente sempre necessário).

3. Escrever as tarefas no Elixir

Escreve as tarefas que vão compilar o SCSS para CSS e copiar e concatenar os ficheiros de JavaScript.

Na tarefa referente ao JavaScript, copiamos e concatenamos os ficheiros necessários para o Foundation funcionar. No mínimo são necessários o “jquery.js” e o “foundation.core.js”. De seguida adicionamos os ficheiros necessários aos componentes que vamos usar (os ficheiros listados são apenas um exemplo). O ficheiro “start_foundation.js” inclui apenas o código necessário para inicializar a Foundation ( $(document).foundation();).

4. Correr o gulp

Finalmente, estás pronto para correr os comandos  gulp ou  gulp watch (para executar automaticamente as tarefas sempre que algum ficheiro seja alterado). Isto vai gerar um ficheiro chamado “app.css” na directoria “public/css” e um ficheiro “all.js” na directoria “public/js” que depois pode ser incluídos nas views.

Nota: Se queres que os ficheiros sejam também minificados deves adicionar a flag --production  ( gulp --production ou  gulp watch --production).

Actualização para Elixir 6

Por alguma razão que eu não consigo entender, o Elixir 6 não suporta Babel. Agora só inclui rollup.js e webpack. Não sei se é possível usar algum destes bundlers com a Foundation, mas, até agora, ainda não o consegui fazer. Se souberes como, deixa um comentário.

Resolvi o problema instalando o Babel e as outras ferramentas necessárias, escrevendo uma tarefa nativa do gulp e chamando essa tarefa na função do elixir. Assim:

1. Instalar as ferramentas necessárias

E requerê-las no topo do gulpfile.js .

2. Escrever a tarefa do gulp

Escreve a tarefa do gulp, fora da função do elixir, que compila os ficheiros com o babel, concatena-os, minifica-os (com o uglify) e escreve o resultado no caminho desejado. De notar que os caminhos relativos, aqui, são diferentes, são relativos à raiz do projecto (onde está o gulpfile.js).

3. Chama a tarefa a partir do elixir

Finalmente, na função do elixir, em vez de chamar mix.babel, chama a tarefa que escreveste. O primeiro parâmetro é o nome da tarefa e o segundo é o caminho onde observar alterações que devam activar a tarefa. Possivelmente, vais queres ajustar isto às tuas necessidades.

Claro, também podes chamar a tarefa directamente a partir da linha de comandos com gulp scripts.

4. Sass

A compilação do sass funciona quase da mesma forma que anteriormente. A única diferença é que agora aceita quatro parâmetros, por isso deve ser chamada da seguinte forma:

Como usar Foundation com Laravel Elixir

Actualização: está disponível uma nova versão deste tutorial.

Quando se fala em frameworks front-end, o Bootstrap (anteriormente conhecido como Twitter Bootstrap) é o mais popular. Mas mais popular não significa melhor, e eu sempre preferi o Foundation. Até agora, para usar o Foundation num projecto com o Laravel, simplesmente fazia uma instalação normal dentro da directoria dos assets. Agora com o lançamento do Elixir podemos simplificar um pouco as coisas e usar apenas um task runner para todas as tarefas que queremos automatizar (compilar SCSS, concatenar ficheiros, correr testes…).

Vamos então ver como usar o Foundation num projecto Laravel.

0. Configurar o Elixir

Antes de começar, devemos garantir que o Elixir está devidamente instalado e configurado. Para isso é necessário ter instalado o Node.js (com  o npm) e o gulp. Depois basta correr o seguinte comando, na raiz do projecto (onde está o ficheiro “package.json”). Mais informação na documentação do Laravel.

O ‘package.json’, por defeito, inclui como dependência o Twitter Bootstrap. Como vamos utilizar o Foundation, podemos apagar a respectiva linha antes de correr o comando anterior. Para remover o Twitter Bootstrap depois de já estar instalado basta correr:

Por esta altura, deve ser possível correr, sem erros, o comando gulp .

1. Instalar o Bower

O Bower é o package manager com que vamos instalar o Foundation. De notar que deve ser instalado globalmente (por isso a flag -g) .

Depois temos que inicializar o Bower. Para isso, ou criamos um ficheiro chamado bower.json (em que o único valor obrigatório é “name”), ou corremos a ferramenta de inicialização:

Não esquecer de adicionar a pasta “bower_components” ao .gitignore

Segundo a página do Foundation no GitHub existe também um package para o npm, o que tornava desnecessário instalar o Bower. Mas, pelo que vi, se instalarmos via npm, nenhuma das dependências (jquery, modernizr, etc…) são instaladas. Por isso a preferência pelo Bower.

2. Instalar o Foundation

Estamos finalmente prontos para instalar o Foundation, com o seguinte comando:

Depois da instalação, na pasta “resources/assets/sass” vamos precisar de dois ficheiros. Este sãos os ficheiros que nós vamos editar.

2.1. Copiar o ficheiro “_settings.scss” da directoria  “bower_components/foundation/scss/foundation” para a directoria “resources/assets/sass”. Este ficheiro contêm todos os parâmetros dos vários elementos do Foundation que podemos personalizar.

2.2. Na directoria ‘resources/assets/sass’ criar um ficheiro chamado app.scss com o seguinte conteúdo.

Este é o ficheiro principal, que faz todos os imports necessários e onde podemos escrever o nosso SCSS. De notar que é preferível importar apenas os componentes que realmente vamos usar, de modo a limitar o tamanho do ficheiro CSS que vai ser gerado. Para isso devemos comentar ou apagar a linha @import "foundation";  e descomentar as linhas necessárias no bloco seguinte.

3. Escrever as tarefas do Elixir

Para terminar, temos apenas que escrever as tarefas do Elixir que vão compilar o SCSS para CSS e copiar alguns ficheiros JavaScript necessários.

Na tarefa do Sass, definimos a opção ‘includePaths’ de forma a podermos simplificar todos os imports nos ficheiros .scss. Esta tarefa vai criar um ficheiro “app.css” na pasta “public/css” que depois podemos usar no nosso site.

Nas tarefas de JavaScript, copiamos e concatenamos os ficheiros necessários para o Foundation funcionar correctamente. No mínimo, são necessários o “jquery.js” e o “foundation.js”. Depois devemos adicionar os ficheiros relativos aos componentes que estamos a utilizar (os ficheiros listados são só um exemplo). O ficheiro “start_foundation.js” inclui apenas o código para inicializar o Foundation.

Isto vai criar um ficheiro “all.js” na directoria “public/js” que depois podemos usar no nosso site.

O ficheiro “modernizr.js” é criado à parte porque, normalmente, este ficheiro deve ser incluído na head do documento HTML, enquanto que o restante pode ser incluído no final.

4. Conclusão

E é isto. Agora, para executar, basta escrever na linha de comandos gulp para executar as tarefas uma vez ou gulp watch para executar as tarefas sempre que há uma alteração num dos ficheiros.

Se quisermos que os ficheiros criados sejam também minificados temos que adicionar a flag ‘–production’ ( gulp --production ou gulp watch --production ).

Resolver o problema do referral spam no Google Analytics

Neste momento, o Google Analytics está com um problema grande, o chamado referral spam. Especialmente em sites com relativamente pouco tráfego, esta situação praticamente inutiliza os dados apresentados.

A Google parece demorar em resolver o problema, por isso, para já, cabe ao utilizador tentar contorná-lo. Felizmente, encontrei este artigo que apresenta uma solução.

Definitive Guide to Removing Referral Spam – Analytics Edge

A solução é mais simples do que se possa pensar. Em vez de filtrar individualmente cada um dos referrers (o que parece que também não funciona muito bem), faz-se um filtro que deixa passar apenas o tráfego que tem origem no site em que o código do Analytics está instalado.

Implementei a solução hoje, vamos ver como resulta.

Alterar a ordem dos custom posts no WordPress

O facto do WordPress não ter nascido como CMS ainda se nota com alguma regularidade. Um exemplo disso é quando queremos mostrar, com uma ordem definida por nós, um série de elementos pertencentes a um custom post type, que por sua vez pertencem a uma custom taxonomy  (num URL do tipo  /<taxonomy-name>/<taxonomy-term>). Por defeito são mostrados por ordem de criação.

Isto implica criar uma nova instância do WP_Query com todos os argumentos necessários para obter o que pretendemos.

Criar o array com os argumentos tem que se lhe diga. Principalmente porque é preciso saber quais são, quais precisamos, quais podemos ignorar, etc. A forma mais simples de criar esse array é aproveitar o trabalho que o WordPress já fez.

Basta aceder ao array da query original e juntar-lhe apenas os argumentos que queremos alterados. Neste exemplo, o orderby e o order. Fazemos isso com a função do PHP array_merge , que concatena uma série de arrays usando sempre os valores do último array em caso de conflito (exactamente o que pretendemos).

Simples e eficaz.

Dica relacionada: Alternativamente a definir a ordem na página de edição de cada post é melhor usar um plugin como o Simple Page Ordering.

Screenshots de qualquer dimensão, com o PhantomJS

O problema

Às vezes precisamos de um screenshot de uma página web com uma resolução diferente da do nosso ecrã. Se essa resolução for menor que a do nosso ecrã, a coisa até se resolve. Redimensiona-se a janela para a dimensão pretendida e usa-se um dos muitos plugins disponíveis, embora nem sempre sejam muito fiáveis se quisermos uma resolução exacta. Se a resolução for maior, torna-se um bocado mais complicado. Se precisarmos de simular uma pixel density maior (aka retina), ainda pior.

Deparei-me com este problema quando precisei de criar screenshots para o meu portefólio. Comprei um daqueles ficheiros .psd com computadores e telemóveis de vários tamanhos. Por alguma razão todos estes ficheiros apresentam produtos Apple e, para funcionar correctamente, precisava de screenshots com uma resolução idêntica à dos Macs e iPhones.

A solução

É aqui que entra o PhantomJS. Uma implementação do Webkit que pode ser manipulada via JavaScript. Tem vários casos de uso. Entre eles, o que nos interessa para hoje, a geração de capturas de ecrã.

O script para fazer isso é bastante simples.

Para obter um screenshot basta gravar este script num ficheiro (por exemplo screenshot.js), editar com os valores pretendidos  e executar o PhamtonJS.

O scale = 2 é o valor que vai simular um ecrã com densidade 2x (só mais ou menos, ver notas). Para um screenshot normal, o valor deve ser 1.

De notar que isto é a forma mais simples de resolver o problema. O script podia ser melhorado de vários formas, nomeadamente aceitar os valores como parâmetros em vez de serem hardcoded no script.

Algumas questões:

  • Usar o scale = 2 não emula completamente um ecrã de alta densidade. Apenas duplica o tamanho do conteúdo, o device pixel ratio continua a ser 1. O que elimina, por exemplo, a possibilidade de gerar correctamente um screenshot de um ecrã de telemóvel.
  • A versão actual (1.9) não suporta Google Web Fonts (mais especificamente ficheiros .woff). Apenas a próxima versão (2.0) resolve este problema. Podem encontrar um build da versão 2, aqui.
  • A altura do viewport parece não ter influência na altura do screenshot. Mas depois de ter o screenshot é fácil de cortar à dimensão correcta.

Opções para escrever código

Já que ando numa de mudanças (CakePHP para Laravel, começar a usar testes para o meu código…) decidi também rever a aplicação que uso para escrever código. Queria principalmente decidir se continuava com um editor de texto normal ou se mudava para um IDE.

Estas foram as opções que considerei (incluindo a minha opção actual):

Editores de texto

Sublime Text

Tem sido a minha escolha (e a de muita gente). É aquilo que um editor de texto deve ser. Leve e fácil de usar mas ao mesmo tempo com funcionalidades capazes de quase rivalizar com um IDE.

Atom

O Atom, produto do GitHub, está em perseguição directa ao Sublime Text e é até bem possível que o venha a ultrapassar. Nota-se que é fortemente inspirado pelo Sublime Text e já rivaliza com ele em muitas funcionalidades. Mas ainda não está tão “polido” e em termos de recursos é mais pesado (pelo menos para já).

IDE’s

PhpStorm

Está para os IDE’s como o Sublime Text está para os editores de texto. É mais ou menos a escolha por defeito. Justificadamente, diga-se. Parece que não há nada que o PhpStorm não faça. Além disso parece ser o mais personalizável dos três que experimentei (O Laracasts tem um curso gratuito sobre o PhpStorm que demonstra bem todas as suas potencialidades).

NetBeans

O NetBeans foi a minha escolha durante os meus tempos de universidade. Na altura, para programar em Java. Não me parece que tenha mudado muito desde essa altura, o que não é, necessariamente, uma coisa má. A primeira coisa que me chamou a atenção foram as sugestões, para termos o código melhor formatado e mais legível. Por exemplo, se tivermos um bloco de código bastante indentado (isto é, dentro de outros blocos) ele sugere, como boa prática, mover esse código para uma nova função.

Embora tenha reparado que é demasiado rigoroso com os avisos e erros. Há até algumas situações em que mostra um erro em linhas de código que não têm problema nenhum, parece-me.

Eclipse

O Eclipse acabou por ser a revelação. Lembro-me dos tempos em que demorava cerca de 2 dias a iniciar e, desta vez, instalei-o apenas para ver como estava. Para surpresa minha, tempo de lançamento perfeitamente normal e memória usada dentro de um nível bastante bom para um IDE. O olho nu parece-me bastante comparável com os outros dois e isto já mostra uma grande evolução em relação ao que era.

Conclusão

Claro que gosto da simplicidade e rapidez de um editor de texto mas não há como negar que um IDE oferece funcionalidades fora do alcance de um editor de texto, que facilitam a escrita do código e poupam bastante tempo.

Fica a questão de que IDE usar. O PhpStorm seria a escolha óbvia, é claramente o mais evoluído dos três que experimentei. Mas é uma aplicação paga e, quando estamos a tentar iniciar uma startup via bootstrap, todos os euros contam.

Ainda estou um pouco indeciso entre o NetBeans e o Eclipse. O NetBeans parece ser mais robusto “out of the box” mas o Eclipse parece ser mais extensível através de plugins. Neste momento, talvez esteja um bocado mais inclinado para o Eclipse (quem diria?) mas acho que, para tirar as teimas, vou tentar usar cada um deles durante um período alargado de tempo (tipo 1 mês) e no fim ver com qual estou mais confortável.

Adeus CakePHP, olá Laravel

LaravelMudei de framework. Adeus CakePHP, olá Laravel. Não estava insatisfeito com o CakePHP mas o Laravel pareceu-me uma framework mais moderna e que convida a melhores práticas de programação. E, como decidi reescrever a Balliza de início, pareceu-me uma boa altura para mudar.

Não é um adeus definitivo ao CakePHP. Aliás, quero ver se começo um pequeno projecto paralelo, em CakePHP, para me manter fluente na framework. Só ainda não sei o quê.

Como alguns dos conceitos são novos para mim (injecção de dependência, inversão de controlo…), os primeiros tempos no Laravel têm dado alguma luta. Mas estou bastante satisfeito por ter feito a mudança. Sinto até, que nas últimas semanas, evoluí consideravelmente como programador (pode ser só impressão minha, mas a verdade é que aprendi bastante).

Acabo com a sugestão de dois recursos que me têm ajudado bastante nos primeiros passos:

  • Laracasts, um site com tutoriais em vídeo que ensina praticamente tudo o que é preciso sobre o Laravel e não só. Alguns dos vídeos estão disponíveis gratuitamente e, por 9 dólares mensais, temos acesso a todo o conteúdo. Na minha opinião, tem sido dinheiro muito bem empregue.
  • Laravel News, um site com links úteis sobre a framework. Subscrevam a newsletter para receberem, uma vez por semana, todas as notícias e artigos.

Site multilingue com o Polylang

Rosetta StoneAndava há uns tempos a pensar em disponibilizar este site em português e inglês. Precisava de um plugin para isso, mas andava a adiar porque as duas opções que conhecia não me agradavam muito.

Um dos plugins, o qTranslate, é gratuito mas a forma como funciona, colocando todas as traduções dentro do mesmo post (com tags próprias), não me agrada muito. Além disso, parece que não consegue acompanhar o desenvolvimento do WordPress. Já me aconteceu não poder actualizar o WordPress por causa do qTranslate. Aliás, isso parece estar a acontecer neste momento. O plugin não é actualizado desde Janeiro e, segundo a informação na página do plugin, não funciona com as versões mais recentes do WordPress.

A outra opção, o WPML, é, penso eu, uma das soluções mais usadas para sites WordPress multilingue e bastante boa, pelo que leio. Mas é um plugin pago e eu não sei se justificaria o investimento. Embora seja interessante ter o site em inglês, não era uma prioridade.

O facto é que, com uma pesquisa rápida, foi fácil encontrar algumas alternativas. Destas, o Polylang, destacou-se. Parece ser relativamente usado (300 mil downloads) e com desenvolvimento activo (última actualização há uns dias).

Depois de configurado e todo o conteúdo traduzido, queria aqui deixar as minhas primeiras impressões sobre o plugin.

Prós

  • Cria um post para cada língua e liga-os como traduções do mesmo artigo. Isto traz algumas vantagens, nomeadamente, cada post ter um link próprio e não ser necessário indicar a linguagem no URL (embora seja possível).
  • Ficamos, automaticamente, com feeds RSS para cada linguagem.
  • Além do tradicional widget, o alternador de linguagem pode ser adicionado como uma entrada de menu, o que facilita bastante a sua inserção no site.
  • Os widgets não são propriamente traduzidos mas temos a opção, para cada um, de o mostrar apenas numa determinada língua. O mesmo com os menus. Todas as zonas de menus são multiplicadas pelo número de línguas, tendo depois que criar um menu para cada uma delas.
  • Várias funções e filtros para serem usados no theme, caso seja necessário (a documentação é bastante boa).

Contras

  • O workflow de escrita pode ser algo tedioso. O Polylang oferece a possibilidade de, entre outras coisas, sincronizar tags e categorias entre traduções, mas, para isso, têm que estar traduzidas. O que quer dizer que, depois de escrever o post original, temos que traduzir tags e categorias (se forem novas) antes de criar as traduções. Além disso, as páginas de media (imagens) também têm que ser traduzidas antes de estarem disponíveis para inserir nas traduções.
  • Não traduz slugs de custom post types. Por exemplo, o endereço ‘zecipriano.com/trabalho’ fica ‘zecipriano.com/en/trabalho’ em vez de termos a possibilidade de traduzir para ‘zecipriano.com/work’.

Conclusão

O WordPress nunca foi pensado para sites multilingue pelo que nenhuma solução será perfeita, mas no geral estou satisfeito com o Polylang. Especialmente tendo em conta que é um plugin gratuito. Tudo funciona como esperado e as desvantagens acabam por ser de pouca relevância.

Finalmente, referir que para termos uma tradução perfeita também é necessário criar, se não existir, uma tradução do theme. Usando as funções do gettext [ __(‘string’) ] e depois traduzindo, por exemplo, com o plugin CodeStyling Localization.

Um melhor ambiente de desenvolvimento com o Vagrant

VagrantRecentemente, comecei a usar o Vagrant para o meu ambiente de desenvolvimento local.

O XAMPP tem cumprido a sua função, até agora, mas chegamos a um ponto em que é necessário uma máquina virtual o mais semelhante possível ao ambiente em produção.

É aqui que entra o Vagrant, que é, de uma forma muito simples (e talvez um pouco enganadora) um gestor de máquinas virtuais.

Permite, apenas com um ficheiro (chamado Vagrantfile ) na raiz do nosso projecto, descrever a máquina que pretendemos usar e instalar o software necessário. Este ficheiro indica a imagem que vai servir de base à nossa máquina virtual e todas as configurações e instalações necessárias.

A imagem de base (designada base box) pode ser uma das muitas disponíveis na net. Embora a fonte principal seja a Vagrant Cloud. Basta indicar o URL da box no Vagrantfile e, se ela ainda não estiver instalada, o download é feito automaticamente. Claro que, em vez de usar uma base box já existente, podemos criar uma de raiz, exactamente com o que precisamos.

Depois desta configuração inicial, de cada vez que precisarmos da máquina, basta escrever o comando ‘vagrant up’. Simples. Outra grande vantagem é que o Vagrantfile pode ser partilhado entre várias pessoas (via Git, por exemplo) de modo a que todas trabalhem com a mesma máquina virtual.

A documentação oficial é bastante boa e deve ser suficiente para a maioria dos casos de uso.

É uma ferramenta que tem uma pequena curva de aprendizagem inicial, especialmente se tentarmos criar a nossa própria base box (este tutorial ajuda) mas que compensa bastante depois de termos todas as arestas limadas.