Opa Fabio, > Eu precisava de algum manual (completo) sobre SelectionWidget para > trabalhar com vocabulários. O ArcheType seria o ATVocabularyManager ou > outro que vocês possam recomendar. Já procurei na documentação que vem > junto com esse Archetype e ele só ensina até uma parte e no google não > obtive resposta satisfatória.
vocabulários não são um mistério tão grande assim... :-) A princípio existem dois tipos básicos de vocabulários que podem ser atribuídos a um field de um schema de um content-type qualquer: estáticos e dinâmicos. Os vocabulários *estáticos* são aqueles onde você passa uma relação fixa de elementos e eles não variam. Exemplos: a) Uma tupla/lista: vocabulary=('maçã', 'kiwi', 'uva') vocabulary=['maçã', 'kiwi', 'uva'] Neste caso, cada valor será usados tanto para exibição na tela como para armazenamento. b) Uma tupla/lista de 2-tuplas: vocabulary=(('0', 'maçã'), ('1', 'kiwi'), ('2', 'uva')) vocabulary=[('0', 'maçã'), ('1', 'kiwi'), ('2', 'uva')] Neste caso, o primeiro valor de cada tupla será usado no armazenamento e o segundo valor é o que será exibido na tela. c) Uma DisplayList: vocabulary=DisplayList(( ('0', 'maçã', 'label_maca'), ('1', 'kiwi', 'label_kiwi'), ('2', 'uva', 'label_uva'), )) Neste caso, o primeiro valor de cada tupla será usado no armazenamento, o terceiro valor será usado como msgid no processo de internacionalização (i18n) e o segundo valor será usado apenas se uma tradução para o terceiro valor não for encontrada. Vale lembrar que os casos (a) e (b) são internamente transformados para uma DisplayList, mas sem usar i18n (sem o terceiro valor). O segundo tipo de vocabulário é o *dinâmico*, onde como o nome diz, a relação dos items não é fixa, podendo ser alterada. Similarmente aos vocabulários estáticos, os dinâmicos devem retornar um dos 3 tipos já descritos, ou seja, uma tupla/lista ou uma tupla/lista de 2-tuplas ou ainda uma DisplayList. Exemplos: d) Uma string: vocabulary='getFrutasDisponiveis' Neste caso, o valor da string é usado como nome do método a ser chamado numa instância do objeto. Além de poder ser um método na classe, ele pode ser também um PythonScript e ficar dentro de uma das skins do portal. Um exemplo de implementação do nosso getFrutasDisponiveis (como um método da classe) poderia ser: def getFrutasDisponiveis(self, content_instance, field): frutas = DisplayList() for fruta in content_instance.listaFrutas(): if fruta.quantidade > 0: frutas.add(fruta.codigo, fruta.nome) return frutas Note que o método recebe dois parâmetros, content_instance e field. O primeiro é a instância a partir da qual o método está sendo chamado e o segundo é o nome do field. Isso é útil quando o mesmo método é usado como vocabulário de campos diferentes. No exemplo, considerei que existe um método listaFrutas que nos retorna a relação de todas as frutas. As frutas ainda possuiriam 3 atributos: quantidade, codigo e nome. Apenas as frutas com uma quantidade maior do que 0 seriam retornadas no nosso vocabulário dinâmico. Vale lembrar que a implementação ao invés de considerar objetos presentes no ZODB, poderia fazer uma chamada SQL, pegando a relação de frutas disponíveis em um banco de dados qualquer. e) Uma instância de uma classe que implementa a interface IVocabulary: vocabulary=NamedVocabulary("frutas") Nesse caso, usamos a classe NamedVocabulary do ATVocacularyManager (ATVM) que implementa a IVocabulary. Considerei que já existe um vocabulário 'frutas' dentro da tool portal_vocabularies, ou seja, bastaria adicionar novos objetos (de um tipo de conteúdo qualquer, configurável) dentro daquele vocabulário para que eles se tornem imediatamente disponíveis. O ATVM é razoavelmente complexo, mas fornece alguns recursos interessantes, como vocabulários hierárquicos e também suporte ao LinguaPlone, para i18n do conteúdo. Bom, 'resumindo' era isso... ;-) HTH, -- Dorneles Treméa X3ng Web Technology