quarta-feira, 8 de agosto de 2007

Pylons, ToscaWidgets e Unicode

Alguns dias atrás o Torcato anunciou que estava iniciando um pequeno projeto pra estudar Pylons, o Ferlons. Logo pedi autorização pra entrar no projeto e conhecer um pouco mais do ToscaWidgets.

Widgets são velhos conhecidos dos desenvolvedores Plone. A idéia é não escrever o formulário HTML, mas construir uma estrutura de dados que represente um campo em nosso esquema. Por exemplo, imagine uma classe usuário, com o nome do usuário e a data da admissão. Em vez de escrever um formulário para esses dados, o uso de widgets nos permite representar essas estruturas programaticamente, de forma que a geração do formulário seja automática e rica, incluindo um javascript para nos mostrar um calendário onde podemos escolher a data, e um pouco de CSS.

O TurboGears já inclui widgets há um bom tempo. Alberto Valderde extraiu os widgets do core do TurboGears e criou o projeto ToscaWidgets, que permite que esse widgets sejam usados por outros frameworks. Em nosso caso, incluímos o ToscaWidgets no Ferlons (Pylons).

Porém, incluí-lo não foi tarefa trivial, porque tivemos dois problemas chatos com Unicode. O método padrão para mostrar o widget renderizado é o display, que retorna um stream. Ao executar um print para esse stream, o resultado é uma string, mas ele tem caracteres Unicode lá dentro. O Mako passa um unicode() no resultado disso daí, e o resultado é um temido UnicodeDecodeError. Após alguns (4 dias :D) de testes, descobri como corrigir: em vez de chamar form.display no meu template, agora chamo form.render().decode('utf-8').

O outro bug era no validador, novamente relacionado com Unicode. Estamos usando o validador UnicodeString do FormEncode, porém ele não funcionava corretamente em nosso formulário. Após uma breve discussão na lista do TurboGears, descobri que o UnicodeString do FormEncode tem um problema com o ToscaWidgets, mas o próprio ToscaWidgets possui um validador Unicode, que funciona corretamente. Na verdade, o método o ToscaWidgets espera que o método from_python retorne uma string Unicode, ao passo que o método from_python do UnicodeString do FormEncode retorna uma string UTF-8. Um exemplo do que estou falando:

>>> from toscawidgets.widgets.forms import validators as tosca_validators


>>> tosca_unicode = tosca_validators.UnicodeString()
>>> tosca_unicode.from_python('é')
'\xc3\xa9'
>>> tosca_unicode.from_python(u'é')
u'\xe9'
>>> import formencode.validators as formencode_validators
>>> formencode_unicode = formencode_validators.UnicodeString()
>>> formencode_unicode.from_python('é')
'\xc3\xa9'
>>> formencode_unicode.from_python(u'é')
'\xc3\xa9'

Agora, livres (eu acho!) dos bugs de Unicode, ficamos livres pra realmente implementar o código. Parece fácil escrevendo aqui, mas tomou uma semana minha pra descobrir isso.

blog comments powered by Disqus