Modelos de travessia e página personalizados
Pergunta
Usando Marius Gedminas Excelente post no blog, Criei um Traverser personalizado para uma pasta no meu site.
Isso me permite mostrar: http://foo.com/folder/random_id
Ao invés de: http://foo.com/folder/object.html?id=random_id
O lado da configuração funciona muito bem, eu posso pegar os Random_ids e pesquisar minhas mensagens para a correta, pronta para ser exibida.
Meu problema é que não tenho certeza de como exibir os dados através dos meus modelos de página habituais - no ponto TODO em seu código original;)
if name == 'mycalendar':
mycalendar = ... # TODO: do something to get the appropriate object
return mycalendar
Normalmente eu usaria algo semelhante a:
class Test(BrowserPage):
template = ViewPageTemplateFile('atest.pt')
def __call__(self):
return self.template()
Mas não posso descobrir como fazer isso corretamente no contexto da travessia personalizada.
ATUALIZAR: Para ficar claro que quero evitar adicionando qualquer outra coisa ao URL (Não: http://foo.com/folder/random_id/read).
EU não Precisa que a visão esteja disponível por meio de qualquer outro endereço (Não: http://foo.com/folder/read)
O ZCML para a visão que eu gostaria de usar é:
<browser:page
for="foo.interfaces.IFooFolderContainer"
name="read"
template="read.pt"
permission="zope.ManageContent"
/>
Estou supondo (em mais conselhos), algo parecido com:
return getMultiAdapter((mycalendar, self.request), IPageTemplate, name=u'read')
Ou mesmo uma visualização padrão para o tipo de objeto (um ditado neste caso) que está sendo devolvido:
<browser:page
for="dict"
name="read"
template="read.pt"
permission="zope.ManageContent"
/>
Solução
Seria mais fácil responder à sua pergunta se você mostrasse o que seu Traverser personalizado está fazendo.
Essencialmente, você quer algo assim:
def publishTraverse(self, request, name):
if name in self.context:
return MyMessageView(self.context[name], request)
# fall back to views such as index.html
view = queryMultiAdapter((self.context, request), name=name)
if view is not None:
return view
# give up and return a 404 Not Found error page
raise NotFound(self.context, name, request)
onde myMessageView pode ser algo tão simples quanto
class MyMessageView(BrowserPage):
__call__ = ViewPageTemplateFile('read.pt')
Isenção de responsabilidade: não tenho certeza se a visualização instanciada diretamente será protegida por um invólucro de segurança; Verifique se seus testes funcionais garantem que os usuários anônimos não possam visualizar mensagens, se é isso que você deseja.
Outras dicas
Se você acabar em um objeto adequado com seu TraverSer personalizado, poderá apenas atingir o nome do modelo e o "contexto" do modelo nesse modelo. Então http://foo.com/folder/random_id/my_template
e no modelo fazer o normal <h1 tal:content="context/title" />
material.
IIUC, o que você deseja é renderizar a visualização 'Read' quando alguém solicita /pasta /random_id. Se for esse o caso, tudo o que você precisa fazer é fazer com que sua travessia retorne um objeto (ifolderContent, talvez) representando um random_id e especifique a página 'View' como o DefaultView para ifolerContent.
O DefaultView é necessário porque não há visualização especificada para o objeto random_id no seu URL.