Пользовательский обход и шаблоны страниц
Используя отличную запись в блоге Мариуса Гедминаса, я создал специальный каталог для папки на моем сайте.
Это позволяет мне показать: http://foo.com/folder/random_id
Вместо: http://foo.com/folder/object.html?id=random_id
Конфигурационная сторона работает отлично, я могу поймать random_ids и искать в моих сообщениях правильное, готовое к отображению.
Моя проблема в том, что я не уверен, как затем отобразить данные через мои обычные шаблоны страниц - в точке 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 (No: 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"
/>
3 ответа
Было бы легче ответить на ваш вопрос, если бы вы показали, что делает ваш пользовательский traverser.
По сути, вы хотите что-то вроде этого:
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')
Отказ от ответственности: я не уверен, что представление, которое вы непосредственно создаете, будет защищено оболочкой безопасности; убедитесь, что ваши функциональные тесты гарантируют, что анонимные пользователи не смогут просматривать сообщения, если вы этого хотите.
Если в результате вы получите нужный объект с вашим пользовательским traverser, вы можете просто добавить имя шаблона и пользовательский "контекст" в этом шаблоне. Так http://foo.com/folder/random_id/my_template
и в шаблоне делай нормально <h1 tal:content="context/title" />
вещи.
IIUC, то, что вы хотите, это сделать представление "чтение", когда кто-то запрашивает / folder / random_id. Если это так, все, что вам нужно сделать, это заставить свой обход вернуть объект (IFolderContent, возможно), представляющий random_id, и указать страницу просмотра в качестве defaultView для IFolderContent.
Требуется defaultView, потому что в вашем URL не указан вид для объекта random_id.