Пользовательские шаблоны обхода и страниц
Вопрос
Использование Мариуса Гедминаса отличный пост в блоге, я создал собственный обходчик для папки на своем сайте.
Это позволяет мне показать: http://foo.com/folder/random_id
Вместо: http://foo.com/folder/object.html?id=random_id
Конфигурация работает отлично, я могу поймать случайные идентификаторы и найти в своих сообщениях правильный, готовый к отображению.
Моя проблема в том, что я не уверен, как затем отображать данные с помощью моих обычных шаблонов страниц - в точке TODO в его исходном коде;)
if name == 'mycalendar':
mycalendar = ... # TODO: do something to get the appropriate object
return mycalendar
Обычно я использую что-то похожее на:
class Test(BrowserPage):
template = ViewPageTemplateFile('atest.pt')
def __call__(self):
return self.template()
Но я не могу понять, как это сделать правильно в контексте пользовательского обхода.
ОБНОВЛЯТЬ:Чтобы внести ясность, я хочу избегать добавление чего-либо еще в URL (Нет: http://foo.com/folder/random_id/read).
я не необходимо, чтобы представление было доступно по любому другому адресу (Нет: http://foo.com/folder/read)
ZCML для представления, которое я хотел бы использовать:
<browser:page
for="foo.interfaces.IFooFolderContainer"
name="read"
template="read.pt"
permission="zope.ManageContent"
/>
Я предполагаю (по дополнительным советам), что-то вроде:
return getMultiAdapter((mycalendar, self.request), IPageTemplate, name=u'read')
Или даже представление по умолчанию для возвращаемого типа объекта (в данном случае dict):
<browser:page
for="dict"
name="read"
template="read.pt"
permission="zope.ManageContent"
/>
Решение
Было бы легче ответить на ваш вопрос, если бы вы показали, что делает ваш пользовательский траверс.
По сути, вы хотите что-то вроде этого:
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)
где MyMessageView может быть чем-то простым, например
class MyMessageView(BrowserPage):
__call__ = ViewPageTemplateFile('read.pt')
Отказ от ответственности:Я не уверен, что представление, которое вы создаете напрямую, будет защищено оболочкой безопасности;убедитесь, что ваши функциональные тесты гарантируют, что анонимные пользователи не смогут просматривать сообщения, если вы этого хотите.
Другие советы
Если вы в конечном итоге найдете правильный объект с помощью своего пользовательского обходчика, вы можете просто добавить имя шаблона и пользовательский «контекст» в этом шаблоне.Так http://foo.com/folder/random_id/my_template
и в шаблоне сделать нормально <h1 tal:content="context/title" />
вещи.
IIUC, вам нужно отображать представление «чтение», когда кто-то запрашивает /folder/random_id.В этом случае все, что вам нужно сделать, это заставить ваш обход возвращать объект (возможно, IFolderContent), представляющий случайный_id, и указать страницу «просмотр» в качестве представления по умолчанию для IFolderContent.
Параметр defaultView необходим, поскольку для объекта random_id в вашем URL-адресе не указано представление.