Размер: 14266
Комментарий:
|
Размер: 56086
Комментарий:
|
Удаления помечены так. | Добавления помечены так. |
Строка 2: | Строка 2: |
{{{#!wiki caution Эта страница еще редактируется }}} |
|
Строка 137: | Строка 143: |
=== Как в коде определить, имеет ли пользователь нужные права? === | == Как в коде определить, имеет ли пользователь нужные права? == |
Строка 158: | Строка 164: |
== Я зарегистрировал PAU в корне сайта, и теперь не могу войти как zope.Manager. Что мне делать? == Запустите отладочную оболочку и снимите регистрацию с утилиты. Это позволит вам войти в сайт с правами, которые определены в '''securitypolicy.zcml'''. Пример: {{{#!highlight python $ ./bin/paster shell debug.ini ... >>> import transaction >>> from zope.component import getSiteManager >>> from zope.app.security.interfaces import IAuthentication >>> lsm = getSiteManager(root) >>> lsm.unregisterUtility(lsm.getUtility(IAuthentication), IAuthentication) >>> transaction.commit() }}} Когда вы выйдете из отладки и запустите сервер, то получите возможность войти на сайт как пользователь, который определен в '''principals.zcml'''. Он должен иметь право '''zope.Manager'''. Во избежание таких ситуаций, либо предоставьте роль менеджера пользователю, который определен в PAU, либо создайте папку глубже корневой, сделайте ее сайтом, и зарегистрируйте PAU в ней. Тогда вы по прежнему сможете входить в корень сайта и иметь полные права. == Как мне настроить аутентификацию (используя PAU)? == {{{#!highlight python site = getSite() sm = site.getSiteManager() pau = PluggableAuthentication() sm['authentication'] = pau sm.registerUtility(pau, IAuthentication) users = PrincipalFolder() sm['authentication']['Users'] = users sm.registerUtility(users, IAuthenticatorPlugin, name="Users") pau.authenticatorPlugins = (users.__name__, ) pau.credentialsPlugins = ( "No Challenge if Authenticated", "Session Credentials" ) }}} == Как мне выйти из BlueBream? == FIXME: Это правильно ? Выход доступен со времен Zope 3.3, но по умолчанию он отключен. Для включения - добавьте следующую строчку в '''etc/site.zcml''': {{{#!highlight xml <adapter factory="zope.app.security.LogoutSupported" /> }}} == Почему я получаю ошибку адаптации ILoginPassword при использовании login.html? == Ссылка: https://mail.zope.org/pipermail/zope3-users/2010-January/008745.html Вопрос: Я получаю такую ошибку, когда пытаюсь зайти на вид '''login.html'''. {{{ .../eggs/zope.principalregistry-3.7.0-py2.5.egg/zope/principalregistry/principalregistry.py", line 82, in unauthorized a = ILoginPassword(request) TypeError: ('Could not adapt', <zope.publisher.browser.BrowserRequest instance URL=http://localhost:9060/@@login.html>, <InterfaceClass zope.authentication.interfaces.ILoginPassword>) }}} Вам следует включить пакет ''zope.login'' в ZCML конфигурацию ('''site.zcml'''), так как регистрация адаптера производится именно там: {{{#!highlightp xml <include package="zope.login" /> }}} = Пользовательский интерфейс = == Как установить z3c.traverser и zope.contentprovider? == ''z3c.traverser'' и ''zope.contentprovider'' - вспомогательные пакеты с хорошими и чистыми док. тестами. Для их установки и запуска не нужно много времени, но эти пакеты не содержат примера конфигурации при добавлении их в проект. Из док. тестов становится ясным (и из ваших собственных, написанных во время тестирования собственного кода), что нужно настроить. Итак, для ''z3c.traverser'': {{{#!highlight xml <!-- register traverser for app --> <view for=".IMallApplication" type="zope.publisher.interfaces.browser.IBrowserRequest" provides="zope.publisher.interfaces.browser.IBrowserPublisher" factory="z3c.traverser.browser.PluggableBrowserTraverser" permission="zope.Public" /> <!-- register traverser plugins --> <!-- my own plugin --> <subscriber for=".IMallApplication zope.publisher.interfaces.browser.IBrowserRequest" provides="z3c.traverser.interfaces.ITraverserPlugin" factory=".traverser.MallTraverserPlugin" /> <!-- and traverser package container traverser --> <subscriber for=".IMallApplication zope.publisher.interfaces.browser.IBrowserRequest" provides="z3c.traverser.interfaces.ITraverserPlugin" factory="z3c.traverser.traverser.ContainerTraverserPlugin" /> }}} И для ''zope.contentprovider'': {{{#!highlight xml <!-- register named adapter for menu provider --> <adapter provides="zope.contentprovider.interfaces.IContentProvider" factory="tfws.menu.provider.MenuProvider" name="tfws.menu" /> <!-- this does the directlyProvides --> <interface interface="tfws.menu.provider.IMenu" type="zope.contentprovider.interfaces.ITALNamespaceData" /> }}} == Как объявить глобальные константы в ZCML? == Ссылка: http://mail.zope.org/pipermail/zope3-users/2006-September/004381.html Можно просто использовать директиву '''<utility>''', и сгруппировать константы в логические участки. __interfaces.py:__ {{{#!highlight python class IDatabaseLoginOptions(Interface): username = Attribute() password = Attribute() }}} __config.py:__ {{{#!highlight python class DatabaseLoginOptions(object): implements(IDatabaseLoginOptions) username = 'foo' password = 'bar' }}} __configure.zcml:__ {{{#!highlight python <utility factory=".config.DatabaseLoginOptions" /> }}} __использование:__ {{{#!highlight python opts = getUtility(IDatabaseLoginOptions) }}} Очевидно, что нужно проделать немного больше работы, нежели просто задекларировать несколько констант в ZCML, но глобальные константы вносят много проблем, неважно, определены они в Python, или в XML. Части вашего приложения предполагают их наличие с очень специфическими именами, а их типы нельзя проверить. == Как установить скин по умолчанию? == Используйте директиву '''browser:defaultSkin''': {{{#!highlight xml <browser:defaultSkin name="skinname" /> }}} Для получения более подробной информации о скинах, обратитесь к [[http://bluebream.zope.org/doc/1.0/manual/skinning.html#man-browser-skinning|документации]]. == Как зарегистрировать контент провайдер без использования менеджера вьюлетов? == Вам нужно создать и зарегистрировать простой адаптер для объекта, запроса и вида, который реализует интерфейс '''IContentProvider''': {{{#!highlight python class LatestNews(object): implements(IContentProvider) adapts(Interface, IDefaultBrowserLayer, Interface) def __init__(self, context, request, view): self.context = context self.request = request self.__parent__ = view def update(self): pass def render(self): return 'Latest news' }}} В ZCML: {{{#!highlight xml <adapter name="latestNews" for="* zope.publisher.interfaces.browser.IDefaultBrowserLayer *" provides="zope.contentprovider.interfaces.IContentProvider" factory=".LatestNews" /> }}} Тогда их можно использовать в TAL шаблонах следующим образом: {{{#!highlight xml <div tal:content="provider latestNews" /> }}} Также, вы, возможно, захотите передать через TAL некие параметры. Для получения информации о том, как это сделать, читайте документацию в ''zope.contentprovider''. Если вы хотите привязать некий контент провайдер к скину, измените '''IDefaultBrowserLayer''' на ваш интерфейс скина. == Как подключить статическое содержимое? == Взгляните на директивы '''<resource>''' и '''<resourceDirectory>''' - они позволяют публиковать статические файлы посредством Zope. Обратитесь к [[http://bluebream.zope.org/doc/1.0/manual/browserresource.html#man-browser-resource|документации по ресурсам браузера]] для получения более полной информации. == Доступны ли исходики сервера Webdav в !BlueBream? == Ссылка: http://mail.zope.org/pipermail/zope3-users/2006-September/004648.html Да, вот ссылка на репозиторий: http://svn.zope.org/zope.webdav/trunk == Как использовать переопределения в сборщике в site.zcml для рецепта zc.zope3recipes:app? == Ссылка: http://mail.zope.org/pipermail/zope3-users/2007-April/006106.html {{{highlight xml <includeOverrides package="myapp" file="overrides.zcml" /> }}} == Как сделать свой траверсинг в !BlueBream? == Обратитесь к этому блогу: http://mg.pov.lt/blog/zope3-custom-traversal.html = Программирование = == Доступна ли документация по API онлайн? == Инфраструктура документации Zope3 обладает возможностью генерации html содержимого на лету. Это делает ее немножко медленной при просмотре на старых машинах. Закешированный вариант документации (а поэтому быстрый) доступен на: http://apidoc.zope.org/++apidoc++/ == Как вытянуть проект/пакет из SVN-репозитория? == Взгляните сюда: http://docs.zope.org/developer/noncommitter-svn.html == Как сделать апгрейд с более старого релиза? == Обновите ''versions.cfg'' и укажите URL версионного файла !BlueBream нового релиза и запустите сборщик. == Нужно ли мне каждый раз перезагружать сервер при изменении файлов кода? == Нет, не нужно, если ві пользуетесь опцией '''--reload''' команды '''paster serve'''. То есть, запускать сервер следует так: {{{#!highlight bash ./bin/paster serve --reload debug.ini }}} {{{#!wiki note Мы рекомендуем писать автоматизированные тесты для просмотра эффекта, который произвели изменения. Вначале это кажется надоедливым, но, войдя в привычку, становится неотъемлимой и полезной частью процесса разработки. }}} == Как автоматически создавать нужный объект при старте приложения? == http://mail.zope.org/pipermail/zope-dev/2007-December/030562.html Вы можете сделать это подписываясь на событие '''IDatabaseOpenedWithRootEvent (из zope.app.appsetup)''' Пример кода: {{{#!highlight python from zope.app.appsetup.interfaces import IDatabaseOpenedWithRootEvent from zope.app.appsetup.bootstrap import getInformationFromEvent import transaction @adapter(IDatabaseOpenedWithRootEvent) def create_my_container(event): db, connection, root, root_folder = getInformationFromEvent(event) if 'mycontainer' not in root_folder: root_folder['mycontainer'] = MyContainer() transaction.commit() connection.close() }}} Потом зарегистрируйте подписчик в ''configure.zcml'': {{{#!highlight xml <subscriber handler="myapp.create_my_container" /> }}} == Как сделать валидацию двух или более полей одновременно? == Представьте себе простой пример: есть объект '''личность'''. Этот объект имеет атрибуты '''name''', '''email''' и '''phone'''. Как реализовать правило валидации, которое определяет, существует ли '''email''' или '''phone''', но необязательно оба. Сначала сделаем вызываемый объект - либо простую функцию, либо вызываемый класс: {{{#!highlight python >>> def contacts_invariant(obj): ... if not (obj.email or obj.phone): ... raise Exception("At least one contact info is required") }}} Теперь, определим интерфейс объекта следующим образом. Используйте функцию '''interface.invariant''' для установки инварианта: {{{#!highlight python >>> class IPerson(interface.Interface): ... ... name = interface.Attribute("Name") ... email = interface.Attribute("Email Address") ... phone = interface.Attribute("Phone Number") ... ... interface.invariant(contacts_invariant) }}} Теперь используйте метод '''validateInvariants''' для валидации: {{{#!highlight python >>> class Person(object): ... interface.implements(IPerson) ... ... name = None ... email = None ... phone = None >>> jack = Person() >>> jack.email = u"jack@some.address.com" >>> IPerson.validateInvariants(jack) >>> jill = Person() >>> IPerson.validateInvariants(jill) Traceback (most recent call last): ... Exception: At least one contact info is required }}} == Как получить родителя location? == Для того, чтобы получить родителя объекта используйте '''zope.traversing.api.getParent(obj)'''. Для получения списка родительских объектов - используйте '''zope.traversing.api.getParents(obj)'''. == Как установить заголовок Content-Type HTTP-запроса? == Из IRC (http://zope3.pov.lt/irclogs/%23zope3-dev.2006-06-20.log.html): {{{ Is there any way using the browser:page directive, that I can specify that the Type of a page rendered is not "text/html" but rather "application/vnd.mozilla.xul+xml"? }}} Используйте '''request.response.setHeader(‘content-type’, ...)''' == Как давать уникальные имена объектам при добавлении в контейнер? == Первое: {{{#!highlight python from zope.app.container.interfaces import INameChooser }}} Имя будет присвоено во время выполнения методов '''create''' и '''createAndAdd''', вот пример: {{{#!highlight python def create(self, data): mycontainer = MyObject() mycontainer.value1 = data['value1'] anotherobj = AnotherObject() anotherobj.anothervalue1 = data['anothervalue1'] namechooser = INameChooser(mycontainer) name = chooser.chooseName('AnotherObj', anotherobj) mycontainer[name] = anotherobj return mycontainer }}} == Как добавить каталог программно? == Ссылка: http://zopetic.googlecode.com/svn/trunk/src/browser/collectorform.py Смотрите пример: {{{#!highlight python from zopetic.interfaces import ITicket from zopetic.interfaces import ICollector from zopetic.ticketcollector import Collector from zope.app.intid.interfaces import IIntIds from zope.app.intid import IntIds from zope.component import getSiteManager from zope.app.catalog.interfaces import ICatalog from zope.app.catalog.catalog import Catalog from zope.security.proxy import removeSecurityProxy from zope.app.catalog.text import TextIndex ... def create(self, data): collector = Collector() collector.description = data['description'] return collector def add(self, object): ob = self.context.add(object) sm = getSiteManager(ob) rootfolder = ob.__parent__ cat = Catalog() rootfolder['cat'] = cat if sm.queryUtility(IIntIds) is None: uid = IntIds() rootfolder['uid'] = uid sm.registerUtility(removeSecurityProxy(uid), IIntIds, '') pass sm.registerUtility(removeSecurityProxy(cat), ICatalog, 'cat') cat['description'] = TextIndex('description', ITicket) self._finished_add = True return ob }}} == Существует ли функция для получения URL Zope объекта? == Ссылка: http://zope3.pov.lt/irclogs/%23zope3-dev.2006-09-25.log.html Используйте: {{{#!highlight python zope.component.getMultiAdapter((the_object, the_request), name='absolute_url') }}} или: {{{#!highlight python zope.traversing.browser.absoluteURL }}} == Как сортировать объекты из BTreeContainer? == Вопрос: Есть ли способ сортировки объектов, возвращаемых методом '''values()''' из '''zope.app.container.btree.BTreeContainer'''? Ссылка: http://zope3.pov.lt/irclogs/%23zope3-dev.2006-09-25.log.html Используйте встроенную функцию '''sorted''' (доступна в Python 2.4 и выше) {{{#!highlight python sorted(my_btree.values()) }}} == Как получить параметры запроса в методе вида? == Ссылка: http://mail.zope.org/pipermail/zope3-users/2006-July/003876.html {{{#!highlight python class MyPageView(BrowserView): def __call__(self): if 'myOperation' in self.request.form: param1 = self.request.form['param1'] param2 = self.request.form['param2'] do_something(param1, param2) }}} !MyPageView должен быть либо видом по умолчанию, который ассоциирован с объектом '''mypage''' или видом с именем '''mypage''', который ассоциирован с объектов '''!RootFolder'''. Есть также альтернатива: {{{#!highlight python class MyPageView(BrowserView): def __call__(self, param1, param2="DEFAULT"): if 'myOperation' in self.request.form: do_something(param1, param2) }}} == Как безопасно использовать Reportlab? == Ref: http://mail.zope.org/pipermail/zope3-users/2006-September/004583.html Используйте мьютекс (mutex) (рекурсивный замок (lock) позволяет это сделать): {{{#!highlight python lock = threading.RLock() lock.acquire() try: ... finally: lock.release() }}} == Почему мой объект не добавляется в журнал изменений (changelog)? == Ссылка: http://mail.zope.org/pipermail/zope3-users/2006-May/003392.html Адаптирован ли он к IKeyReference? Если вы используете ZODB, наследования от '''Persistent''' будет достаточно. == Как добавлять новые интерфейсы в существующие компоненты/классы? == Ссылка: http://mail.zope.org/pipermail/zope3-users/2006-November/004918.html Это можно сделать с помощью zcml: {{{#!highlight xml <class class="zope.app.file.Image"> <implements interface=".interfaces.IBloggable" /> </class> }}} == Как получить запрос в обработчике события? == Вопрос: Как получить IRequest в обработчике событий (имею только context)? Ссылка: http://mail.zope.org/pipermail/zope3-users/2007-April/006051.html {{{#!highlight python import zope.security.management import zope.security.interfaces import zope.publisher.interfaces def getRequest(): i = zope.security.management.getInteraction() # raises NoInteraction for p in i.participations: if zope.publisher.interfaces.IRequest.providedBy(p): return p raise RuntimeError('Could not find current request.') }}} == Как создавать ленты RSS? == Обратитесь к http://kpug.zwiki.org/ZopeCreatingRSS (Взят из старого zope-cookbook.org) == Где взять документацию по синтаксису zope.conf? == Ссылка: http://zope3.pov.lt/irclogs/%23zope3-dev.2008-04-01.log.html Обратитесь к '''schema.xml''' внутри яйца ''zope.app.appsetup''. Этот xml файл укажет на остальную часть синтаксиса. Информация о теге '''<zodb>''' находится в яйце ZODB в файле ''component.xml'' == Как зарегистрировать браузерный ресурс в тесте? == Сначала создайте фабрику '''fileresource''' (или imageresourcefactory, или другой): {{{#!highlight python from zope.app.publisher.browser.fileresource import FileResourceFactory from zope.security.checker import CheckerPublic path = 'path/to/file.png' registration_name = 'file.png' factory = FileResourceFactory(path, CheckerPublic, name) Then register it for your layer: from zope.component import provideAdapter provideAdapter(factory, (IYourLayer,), Interface, name) }}} == Как получить зарегистрированный браузерный ресурс в тесте? == Ресурс - просто адаптер на запрос. Он может быть получен в любом контексте. Вы можете получить !FileResource или !DirectoryResource следующим образом: {{{#!highlight python getAdapter(request, name='file.png') }}} Если это папка ресурсов, то так: {{{#!highlight python getAdapter(request, name='img_dir')['foobar.png'] }}} Тогда получите содержимое файла с помощью GET метода (хотя он не является частью какого-либо интерфейса): {{{#!highlight python getAdapter(request, name='img_dir')['foobar.png'].GET() }}} == Как заменить стандартную страницу ошибки 404? == Зарегистрируйте вид для '''zope.publisher.interfaces.INotFound''' в своем слое. По умолчанию используется вид '''zope.app.exception.browser.notfound.NotFound'''. Существует эквивалент для пейджлетов (pagelets): '''z3c.layer.pagelet.browser.NotFoundPagelet''' == Как удалить целое дерево объектов? == Вы не можете управлять порядком удаления. Проблема в том, что определенные объекты удаляются слишком рано, в то время как они нужны другим объектам, особенно, если вы определили адаптеры к '''IObjectRemoved'''. В общем случае нужно вручную создавать дерево зависимостей для удаления, и устанавливать порядок удаления самостоятельно. Одна из проблем, которую провоцируют события в том, что их порядок строго не определен. = Конфигурация и настройка = == Как отключить выбор скина по URL? == FIXME: переопределить траверсинг пространства имен '''++skin++'''? == Как установить z3c.traverser и zope.contentprovider? == 'z3c.traverser'' и ''zope.contentprovider'' - вспомогательные пакеты с хорошими и чистыми док. тестами. Для их установки и запуска не нужно много времени, но эти пакеты не содержат примера конфигурации при добавлении их в проект. Из док. тестов становится ясным (и из ваших собственных, написанных во время тестирования собственного кода), что нужно настроить. Итак, для ''z3c.traverser'': {{{#!highlight xml <!-- register traverser for app --> <view for=".IMallApplication" type="zope.publisher.interfaces.browser.IBrowserRequest" provides="zope.publisher.interfaces.browser.IBrowserPublisher" factory="z3c.traverser.browser.PluggableBrowserTraverser" permission="zope.Public" /> <!-- register traverser plugins --> <!-- my own plugin --> <subscriber for=".IMallApplication zope.publisher.interfaces.browser.IBrowserRequest" provides="z3c.traverser.interfaces.ITraverserPlugin" factory=".traverser.MallTraverserPlugin" /> <!-- and traverser package container traverser --> <subscriber for=".IMallApplication zope.publisher.interfaces.browser.IBrowserRequest" provides="z3c.traverser.interfaces.ITraverserPlugin" factory="z3c.traverser.traverser.ContainerTraverserPlugin" /> }}} И для ''zope.contentprovider'': {{{#!highlight xml <!-- register named adapter for menu provider --> <adapter provides="zope.contentprovider.interfaces.IContentProvider" factory="tfws.menu.provider.MenuProvider" name="tfws.menu" /> <!-- this does the directlyProvides --> <interface interface="tfws.menu.provider.IMenu" type="zope.contentprovider.interfaces.ITALNamespaceData" /> }}} = Как объявить глобальные константы в ZCML? == Ссылка: http://mail.zope.org/pipermail/zope3-users/2006-September/004381.html Можно просто использовать директиву '''<utility>''', и сгруппировать константы в логические участки. __interfaces.py:__ {{{#!highlight python class IDatabaseLoginOptions(Interface): username = Attribute() password = Attribute() }}} __config.py:__ {{{#!highlight python class DatabaseLoginOptions(object): implements(IDatabaseLoginOptions) username = 'foo' password = 'bar' }}} __configure.zcml:__ {{{#!highlight python <utility factory=".config.DatabaseLoginOptions" /> }}} __использование:__ {{{#!highlight python opts = getUtility(IDatabaseLoginOptions) }}} Очевидно, что нужно проделать немного больше работы, нежели просто задекларировать несколько констант в ZCML, но глобальные константы вносят много проблем, неважно, определены они в Python, или в XML. Части вашего приложения предполагают их наличие с очень специфическими именами, а их типы нельзя проверить. == Как зарегистрировать контент провайдер без использования менеджера вьюлетов? == Вам нужно создать и зарегистрировать простой адаптер для объекта, запроса и вида, который реализует интерфейс '''IContentProvider''': {{{#!highlight python class LatestNews(object): implements(IContentProvider) adapts(Interface, IDefaultBrowserLayer, Interface) def __init__(self, context, request, view): self.context = context self.request = request self.__parent__ = view def update(self): pass def render(self): return 'Latest news' }}} В ZCML: {{{#!highlight xml <adapter name="latestNews" for="* zope.publisher.interfaces.browser.IDefaultBrowserLayer *" provides="zope.contentprovider.interfaces.IContentProvider" factory=".LatestNews" /> }}} Тогда их можно использовать в TAL шаблонах следующим образом: {{{#!highlight xml <div tal:content="provider latestNews" /> }}} Также, вы, возможно, захотите передать через TAL некие параметры. Для получения информации о том, как это сделать, читайте документацию в ''zope.contentprovider''. Если вы хотите привязать некий контент провайдер к скину, измените '''IDefaultBrowserLayer''' на ваш интерфейс скина. == Как подключить статическое содержимое? == Взгляните на директивы '''<resource>''' и '''<resourceDirectory>''' - они позволяют публиковать статические файлы посредством Zope. Обратитесь к [[http://bluebream.zope.org/doc/1.0/manual/browserresource.html#man-browser-resource|документации по ресурсам браузера]] для получения более полной информации. == Доступны ли исходики сервера Webdav в !BlueBream? == Ссылка: http://mail.zope.org/pipermail/zope3-users/2006-September/004648.html Да, вот ссылка на репозиторий: http://svn.zope.org/zope.webdav/trunk == Как использовать переопределения в сборщике в site.zcml для рецепта zc.zope3recipes:app? == Ссылка: http://mail.zope.org/pipermail/zope3-users/2007-April/006106.html {{{highlight xml <includeOverrides package="myapp" file="overrides.zcml" /> }}} == Как сделать свой траверсинг в !BlueBream? == Обратитесь к этому блогу: http://mg.pov.lt/blog/zope3-custom-traversal.html == Как сделать, чтобы мой проект, или другой, появился в APIDOC? == Добавьте следующее в свой '''apidoc.zcml''' или '''configure.zcml''': {{{#!highlight xml <apidoc:rootModule module=”myproject” /> }}} Если он не показывается, добавьте следующее: {{{#!highlight xml <apidoc:moduleImport allow=”true” /> }}} == Как в коде определить, запущено ли приложение в режиме разработки (devmode) или нет? == {{{#!highlight python from zope.app.appsetup.appsetup import getConfigContext def is_devmode_enabled(): """Is devmode enabled in zope.conf?""" config_context = getConfigContext() return config_context.hasFeature('devmode') }}} = Другое = == Как проверить, предоставляет ли объект некоторый интерфейс? == Используйте '''providedBy''', который доступен для интерфейса, он возвращает True, если объект предоставляет интерфейс, и False, если нет. Пример: {{{#!highlight python >>> IMyInterface.providedBy(myobject) True }}} == Как запустить отдельный тест из пакета? == {{{#!highlight bash $ ./bin/test -vpu --dir package/tests test_this_module }}} Замените ‘package’ на имя вашего пакета. == Как записать сессию? == Воспользуйтесь замечательным (и минималистичным) пакетом от Shane Hathaways’ - '''tcpwatch'''. Он записывает все данные, которые передаются между клиентом и сервером, их можно использовать при разработке тестов. Для записи сессии: {{{#!highlight bash $ mkdir record $ tcpwatch.py -L8081:8080 -r record # Note: use the "-s" option if you don't need a GUI (Tk). }}} == Как протестировать загрузку файлов с помощью zope.testbrowser? == Ссылка: http://mail.zope.org/pipermail/zope3-users/2006-July/003830.html Пример: {{{#!highlight python >>> import StringIO >>> myPhoto = StringIO.StringIO('my photo') >>> control = user.getControl(name='photoForm.photo') >>> fileControl = control.mech_control >>> fileControl.add_file(myPhoto, filename='myPhoto.gif') >>> user.getControl(name='photoForm.actions.add').click() >>> imgTag = 'src="http://localhost/++skin++Application/000001/0001/1/photo"' >>> imgTag in user.contents True }}} == Почему я получаю !ForbiddenAttribute исключения/ошибки? == Ссылка: http://mail.zope.org/pipermail/zope3-users/2006-August/004027.html !ForbiddenAttribute - всегда (ВСЕГДА!!!) знак того, что пропущены настройки безопасности, или код пытается получить доступ туда, куда не должен обращаться. Если вы пытаетесь использовать известный метод, вы определенно не сделали настроек безопасности для него. Zope, по умолчанию, устанавливает отказ на доступ к атрибутам и методам, если нет явных настроек. == Атрибут order отсутствует в директиве browser:menuItem? == Вопрос: Я хочу добавить новую закладку в ZMI, чтобы получить возможность редактирования атрибутов неких объектов. Следовательно, я добавляю новый '''menuItem''' в меню '''zmi_views''' через ZCML: {{{#!highlight xml <browser:menuItem action="properties.html" for=".mymodule.IMyClass" title="properties" menu="zmi_views" permission="zope.ManageContent" order="2" /> }}} (!MyClass - просто наследник Folder с дополнительными атрибутами). Проблема в следующем: новая вкладка всегда появляется на первом месте. Я бы хотел, чтобы она появлялась поле вкладки '''content''', а не перед ней. Директива '''order''' не работает. Как мне перенастроить порядок отображения вкладок, чтобы моя вкладка находилась на 2-м месте? Реализация меню по умолчанию сортирует вкладки по интерфейсу, а в вашем варианте - вкладка наиболее специфическая для интерфейса. Обратитесь к ''zope.app.publisher.browser.menu''. Если вам не нравится такое поведение, вам следует переопределить его в коде вашего меню. == Почему при запуске выдается ошибка импорта zlib? == Когда вы компилируете Python, убедитесь, что вы установили библиотеку zlib (development). == Я получаю ошибку Server Error, когда делаю то, что должно работать. Как сделать отладку? == Вот хорошо отформатированный IRC лог, объясняющий как Steve Alexander нашел некий баг; он дает много хороших советов об отслеживании ошибок: http://dev.zope.org/Members/spascoe/HowOneZope3BugWasFixed (Scott Pascoe) Ken Manheimer написал глубокий обзор интерактивной отладки в Zope через консоль Python. Хотя статья написана для Zope 2, много принципов остаются теми же, а некоторые техники актуальны для переноса на !BlueBream. Вот ссылка: http://www.zope.org/Members/klm/ZopeDebugging Вот ‘Using the Zope Debugger’ из документации Zope3: http://svn.zope.org/*checkout*/Zope3/trunk/doc/DEBUG.txt == Не вижу исходников при отладке кода в яйцах == Когда вы пытаетесь шагнуть в такой код (библиотеки), то обнаружите, что файл исходника, на который ссылаетесь - неправильный. Более глубокая проверка показывает, что путь к исходнику содержит неверную часть, похожую на это: '''tmpXXXXX'''. Поправить это очень просто, но сначала почему это происходит: Когда вы устанавливаете яйца с помощью ''easy_install'', он создает временную папку, и компилирует код. Следовательно, ''.pyc'' файлы, которые созданы таким образом обращаются к этой (рабочей, но временной) папке. Потом ''Easy_install'' копирует всю папку в нужное место, так что ''.pyc'' файлы остаются с неправильными ссылками на исходники. Для решения проблемы, просто удалите все ''.pyc'' файлы с ''.egg'' путей, которые у вас есть. На Unix следующее: {{{#!highlight bash find . -name "*.pyc" | xargs rm }}} должно сработать. == Каким образом я могу получить последнее сообщение отладчика, когда запрос вызывает исключение? == В файле ''debug.ini'' обновите раздел [filter-app:main], как указано в комментарии ниже: {{{#!highlight ini [filter-app:main] # Change the last part from 'ajax' to 'pdb' for a post-mortem debugger # on the console: use = egg:z3c.evalexception#ajax next = zope }}} Перезагрузите сервер (вам нужна консоль для взаимодействия с отладчиком): {{{#!highlight bash ./bin/paster serve debug.ini }}} Теперь, когда запрос вызывает исключение, вы будете закинуты в последнюю точку отладки, в точку, где возникло исключение. == Как использовать ZODB blob? == Вы можете использовать реализацию ''z3c.blobfile'' для хранения изображений или других файлов. В !BlueBream, blob хранилище настроено по умолчанию. Конфигурация Zope находится в ''etc/zope.conf'': {{{#!highlight xml <zodb> <filestorage> path var/filestorage/Data.fs blob-dir var/blob </filestorage> ... }}} '''blob-dir''' определяет папку, в которой будут хранится blob-поля. == Как очистить историю (упаковать) ZODB? == Из отладочной оболочки вызовите функцию ''app.db.pack'': {{{#!highlight python $ ./bin/paster shell debug.ini >>> app.db.pack() }}} |
Часто задаваемые вопросы
- Эта страница еще редактируется
Содержание
-
Общее
- Что такое BlueBream?
- Почему BlueBream?
- Что такое Zope Foundation?
- Как Я могу помочь?
- Под какой лицензией выпускается BlueBream?
- Стабилен ли BlueBream достаточно для того, чтобы использовать на производственных серверах
- Какая версия Python необходима для работы BlueBream?
- Что такое KGS (Known Good Set)?
- Как мне создать новый BlueBream проект?
- Концепции
-
Безопасность
- Как настроить несколько классов с одинаковыми правами доступа?
- Как в коде определить, имеет ли пользователь нужные права?
- Я зарегистрировал PAU в корне сайта, и теперь не могу войти как zope.Manager. Что мне делать?
- Как мне настроить аутентификацию (используя PAU)?
- Как мне выйти из BlueBream?
- Почему я получаю ошибку адаптации ILoginPassword при использовании login.html?
-
Пользовательский интерфейс
- Как установить z3c.traverser и zope.contentprovider?
- Как объявить глобальные константы в ZCML?
- Как установить скин по умолчанию?
- Как зарегистрировать контент провайдер без использования менеджера вьюлетов?
- Как подключить статическое содержимое?
- Доступны ли исходики сервера Webdav в !BlueBream?
- Как использовать переопределения в сборщике в site.zcml для рецепта zc.zope3recipes:app?
- Как сделать свой траверсинг в !BlueBream?
-
Программирование
- Доступна ли документация по API онлайн?
- Как вытянуть проект/пакет из SVN-репозитория?
- Как сделать апгрейд с более старого релиза?
- Нужно ли мне каждый раз перезагружать сервер при изменении файлов кода?
- Как автоматически создавать нужный объект при старте приложения?
- Как сделать валидацию двух или более полей одновременно?
- Как получить родителя location?
- Как установить заголовок Content-Type HTTP-запроса?
- Как давать уникальные имена объектам при добавлении в контейнер?
- Как добавить каталог программно?
- Существует ли функция для получения URL Zope объекта?
- Как сортировать объекты из BTreeContainer?
- Как получить параметры запроса в методе вида?
- Как безопасно использовать Reportlab?
- Почему мой объект не добавляется в журнал изменений (changelog)?
- Как добавлять новые интерфейсы в существующие компоненты/классы?
- Как получить запрос в обработчике события?
- Как создавать ленты RSS?
- Где взять документацию по синтаксису zope.conf?
- Как зарегистрировать браузерный ресурс в тесте?
- Как получить зарегистрированный браузерный ресурс в тесте?
- Как заменить стандартную страницу ошибки 404?
- Как удалить целое дерево объектов?
-
Конфигурация и настройка
- Как отключить выбор скина по URL?
- Как установить z3c.traverser и zope.contentprovider?
- Как зарегистрировать контент провайдер без использования менеджера вьюлетов?
- Как подключить статическое содержимое?
- Доступны ли исходики сервера Webdav в !BlueBream?
- Как использовать переопределения в сборщике в site.zcml для рецепта zc.zope3recipes:app?
- Как сделать свой траверсинг в !BlueBream?
- Как сделать, чтобы мой проект, или другой, появился в APIDOC?
- Как в коде определить, запущено ли приложение в режиме разработки (devmode) или нет?
-
Другое
- Как проверить, предоставляет ли объект некоторый интерфейс?
- Как запустить отдельный тест из пакета?
- Как записать сессию?
- Как протестировать загрузку файлов с помощью zope.testbrowser?
- Почему я получаю !ForbiddenAttribute исключения/ошибки?
- Атрибут order отсутствует в директиве browser:menuItem?
- Почему при запуске выдается ошибка импорта zlib?
- Я получаю ошибку Server Error, когда делаю то, что должно работать. Как сделать отладку?
- Не вижу исходников при отладке кода в яйцах
- Каким образом я могу получить последнее сообщение отладчика, когда запрос вызывает исключение?
- Как использовать ZODB blob?
- Как очистить историю (упаковать) ZODB?
Общее
Что такое BlueBream?
BlueBream - готовый к использованию свободный/с открытым исходным кодом фреймворк для создания веб приложений, написанный на языке программирования Python. BlueBream предоставляет компонентную архитектуру, транзакционную объектную базу данных, хорошо интегрированную модель безопасности и много других возможностей.
BlueBream берет свое начало из сообщества Zope, созданного в 1998 году. Изначально основополагающие технологии Zope были разработаны в Zope Corporation. Разработка BlueBream началась в конце 2001 года. В ноябре 2004 года была выпущена первая версия. BlueBream - полностью переписанный вариант, который сохраняет только объектную базу данных ZODB. Архитектура BlueBream порождена потребностями больших компаний, и нацелена на создание корпоративных (enterprise) веб приложений с использованием новейших парадигм в разработке программного обеспечения. На проект очень сильно повлияла концепция экстремального программирования, поэтому для ускорения процесса разработки BlueBream проводятся спринты. В 2006 году был создан фонд Zope, целью которого стала помощь в организации и создании связей с сообществом Zope.
Почему BlueBream?
Вот несколько особенностей, которые отличают BlueBream от других веб фреймворков языка Python:
BlueBream построен на базе Zope Tool Kit (ZTK), который разрабатывался много лет и доказал свою надежность и соответствие потребностям к разработки стабильного, масштабируемого программного обеспечения.
BlueBream использует мощную и известную систему сборки Buildout, созданную на языке Python.
BlueBream использует Zope Object Database (ZODB) - транзакционную объектную базу данных, которая обеспечивает мощный и простой в использовании механизм долгосрочного хранения.
BlueBream регистрирует компоненты с помощью Zope Component Markup Language (ZCML) - языка конфигураций, основанном на XML, который обеспечивает безграничную гибкость.
BlueBream может также регистрировать компоненты используя GROK, который добавляет новый слой конфигурации, замещая декларативную конфигурацию ZCML конвенциями и объявлениями в стандартах Python.
BlueBream обладает Zope Component Architecture (ZCA), которая реализует разделение задач для создания высоко-связуемых компонентов повторного использования (zope.component).
BlueBream реализует Python Web Server Gateway Interface WSGI путем использования Paste, PasteScript, и PasteDeploy.
BlueBream включает множество хорошо оттестированных компонентов, которые реализуют общие задачи. Вот несколько из них:
zope.publisher публикует объекты Python в веб окружении, поддерживая совместимость с WSGI
zope.security предоставляет общий механизм подключаемых политик безопасности policies
zope.testing и zope.testbrowser предлагают фреймворки для unit- и функционального тестирования
zope.pagetemplate - XHTML-совместимый язык разработки шаблонов
zope.schema - механизм схем
zope.formlib - инструмент для автоматической генерации форм
BlueBream - свободное/с открытым исходным кодом программное обеспечение, является собственностью Zope Foundation. !Bluebream выпускается под лицензией Zope Public License (BSD-подобная, GPL-совместимая лицензия).
Что такое Zope Foundation?
Из http://foundation.zope.org:
Целью Zope Foundation является продвижение, управление, и разработка платформы Zope. Достигается цель путем поддержки сообщества Zope. Наше сообщество включает открытое сообщество вкладчиков в программное обеспечение Zope, вкладчиков в документацию и веб инфраструктуру, а также сообщество предприятий и организаций, использующих Zope. Zope Foundation владеет авторскими правами на программное обеспечение Zope, множества расширений и связанного программного обеспечения. Zope Foundation также управляет сайтом ''zope.org'' и инфраструктурой сотрудничества.
Для более подробной информации обратитесь к: http://foundation.zope.org/about
Как Я могу помочь?
Если вы заинтересованы в оказании помощи сообществу, у вам есть время, - обучитесь компонентной архитектуре и BlueBream, и принимайте участие в любой из областей разработки. Посещайте на IRC канал: #bluebream at irc.freenode.net. Также присоединяйтесь к спискам рассылки: https://mail.zope.org/mailman/listinfo/bluebream. Вот вики страница с более подробной информацией: http://wiki.zope.org/bluebream/ContributingToBlueBream.
Под какой лицензией выпускается BlueBream?
BlueBream выпускается под лицензией Zope Public License (BSD-подобная, GPL-совместимая лицензия).
Стабилен ли BlueBream достаточно для того, чтобы использовать на производственных серверах
Да, он достаточно стабилен для использования в производственном (production) окружении. BlueBream (раньше Zope 3) уже используется в ряде больших проектов. Разработка BlueBream, наверное, никогда не закончится, по крайней мере, пока он соответствует нашим требованиям
Какая версия Python необходима для работы BlueBream?
BlueBream 1.0 поддерживает следующие версии языка Python:
- Python 2.4
- Python 2.5
- Python 2.6
Если вы используете 64-битную платформу, рекомендуется использовать Python 2.6.
Что такое KGS (Known Good Set)?
Начиная с версии Zope 3.4, Zope 3 (BlueBream) разделен на маленькие пакеты, называемые "яйцами", которые выпускаются независимо друг от друга. KGS - набор таких яиц, которые известны как хорошо работающие вместе. Их список можно найти в версионном файле Buildout.
Индекс пакета KGS для zope 3.4: http://download.zope.org/zope3.4/ Новые версии файла будут доступны здесь: http://download.zope.org/bluebream/
Как мне создать новый BlueBream проект?
Обратитесь к разделу документации Первые шаги.
Концепции
Что такое компонентная архитектура
Она очень похожа на другие компонентные архитектуры и позволяет приспосабливать маленькие куски программного кода для совместной работы.
Где я могу найти ссылки на ресурсы?
Официальный сайт (обновляется один раз в день)
Зеркало (Обновляется раз в 30 минут)
IRC Канал: #bluebream на freenode.net
Ohloh.net: https://www.ohloh.net/p/bluebream
Buildbots: http://buildbot.afpy.org/bluebream/ http://bluebream.buildbot.securactive.org/
- Вики страницы сообщества
Что такое /@@ и какой его синтаксис?
@@ - сокращенная форма записи для ++view++. (Мнемонически, это выглядит как пара глаз)
Для того, чтобы указать, что вы хотите получить вид с именем bar контент-объекта foo, вам необходимо (в компактной форме) перейти по ссылке .../foo/@@bar вместо .../foo/++view++bar.
Заметьте также, что даже @@ не нужен, если контейнер foo не содержит элемента с именем bar - он служит только для того, чтобы различать виды и содержимое контейнера.
@@ также используется для статических ресурсов. Для получения доступа к зарегистрированному статическому ресурсу с именем logo.png, вы можете использовать /@@/logo.png, или его эквивалент /++resource++logo.png. logo.png - это регистрационное имя файла, при этом физическое имя файла может быть совсем другим.
То же самое касается и папки ресурсов с именем images: /@@/images/logo.png эквивалентно /++resource++images/logo.png. В этом случае, logo.png - реальное имя файла, размещенного в зарегистрированной папке с ресурсами.
Безопасность
Как настроить несколько классов с одинаковыми правами доступа?
Ссылка: http://mail.zope.org/pipermail/zope3-users/2007-June/006291.html
Используйте атрибут like_class тега required, ниже несколько примеров:
Как в коде определить, имеет ли пользователь нужные права?
Ссылка: http://mail.zope.org/pipermail/zope3-users/2006-August/004201.html
Вопрос: как мне узнать, имеет ли текущий пользователь права на некий вид? Вот примерное решение:
Используйте zope.security.canAccess и/или zope.security.canWrite.
Для определения других прав на объект, можно сделать примерно следующее:
Я зарегистрировал PAU в корне сайта, и теперь не могу войти как zope.Manager. Что мне делать?
Запустите отладочную оболочку и снимите регистрацию с утилиты. Это позволит вам войти в сайт с правами, которые определены в securitypolicy.zcml.
Пример:
1 $ ./bin/paster shell debug.ini
2 ...
3 >>> import transaction
4 >>> from zope.component import getSiteManager
5 >>> from zope.app.security.interfaces import IAuthentication
6 >>> lsm = getSiteManager(root)
7 >>> lsm.unregisterUtility(lsm.getUtility(IAuthentication), IAuthentication)
8 >>> transaction.commit()
Когда вы выйдете из отладки и запустите сервер, то получите возможность войти на сайт как пользователь, который определен в principals.zcml. Он должен иметь право zope.Manager.
Во избежание таких ситуаций, либо предоставьте роль менеджера пользователю, который определен в PAU, либо создайте папку глубже корневой, сделайте ее сайтом, и зарегистрируйте PAU в ней. Тогда вы по прежнему сможете входить в корень сайта и иметь полные права.
Как мне настроить аутентификацию (используя PAU)?
1 site = getSite()
2 sm = site.getSiteManager()
3 pau = PluggableAuthentication()
4 sm['authentication'] = pau
5 sm.registerUtility(pau, IAuthentication)
6 users = PrincipalFolder()
7 sm['authentication']['Users'] = users
8 sm.registerUtility(users, IAuthenticatorPlugin, name="Users")
9 pau.authenticatorPlugins = (users.__name__, )
10 pau.credentialsPlugins = ( "No Challenge if Authenticated", "Session Credentials" )
Как мне выйти из BlueBream?
FIXME: Это правильно ?
Выход доступен со времен Zope 3.3, но по умолчанию он отключен. Для включения - добавьте следующую строчку в etc/site.zcml:
1 <adapter factory="zope.app.security.LogoutSupported" />
Почему я получаю ошибку адаптации ILoginPassword при использовании login.html?
Ссылка: https://mail.zope.org/pipermail/zope3-users/2010-January/008745.html
Вопрос: Я получаю такую ошибку, когда пытаюсь зайти на вид login.html.
.../eggs/zope.principalregistry-3.7.0-py2.5.egg/zope/principalregistry/principalregistry.py", line 82, in unauthorized a = ILoginPassword(request) TypeError: ('Could not adapt', <zope.publisher.browser.BrowserRequest instance URL=http://localhost:9060/@@login.html>, <InterfaceClass zope.authentication.interfaces.ILoginPassword>)
Вам следует включить пакет zope.login в ZCML конфигурацию (site.zcml), так как регистрация адаптера производится именно там:
<include package="zope.login" />
Пользовательский интерфейс
Как установить z3c.traverser и zope.contentprovider?
z3c.traverser и zope.contentprovider - вспомогательные пакеты с хорошими и чистыми док. тестами. Для их установки и запуска не нужно много времени, но эти пакеты не содержат примера конфигурации при добавлении их в проект. Из док. тестов становится ясным (и из ваших собственных, написанных во время тестирования собственного кода), что нужно настроить. Итак, для z3c.traverser:
1 <!-- register traverser for app -->
2 <view
3 for=".IMallApplication"
4 type="zope.publisher.interfaces.browser.IBrowserRequest"
5 provides="zope.publisher.interfaces.browser.IBrowserPublisher"
6 factory="z3c.traverser.browser.PluggableBrowserTraverser"
7 permission="zope.Public"
8 />
9
10 <!-- register traverser plugins -->
11 <!-- my own plugin -->
12 <subscriber
13 for=".IMallApplication
14 zope.publisher.interfaces.browser.IBrowserRequest"
15 provides="z3c.traverser.interfaces.ITraverserPlugin"
16 factory=".traverser.MallTraverserPlugin"
17 />
18 <!-- and traverser package container traverser -->
19 <subscriber
20 for=".IMallApplication
21 zope.publisher.interfaces.browser.IBrowserRequest"
22 provides="z3c.traverser.interfaces.ITraverserPlugin"
23 factory="z3c.traverser.traverser.ContainerTraverserPlugin"
24 />
И для zope.contentprovider:
1 <!-- register named adapter for menu provider -->
2 <adapter
3 provides="zope.contentprovider.interfaces.IContentProvider"
4 factory="tfws.menu.provider.MenuProvider"
5 name="tfws.menu"
6 />
7
8 <!-- this does the directlyProvides -->
9 <interface
10 interface="tfws.menu.provider.IMenu"
11 type="zope.contentprovider.interfaces.ITALNamespaceData"
12 />
Как объявить глобальные константы в ZCML?
Ссылка: http://mail.zope.org/pipermail/zope3-users/2006-September/004381.html
Можно просто использовать директиву <utility>, и сгруппировать константы в логические участки.
interfaces.py:
config.py:
configure.zcml:
1 <utility factory=".config.DatabaseLoginOptions" />
использование:
1 opts = getUtility(IDatabaseLoginOptions)
Очевидно, что нужно проделать немного больше работы, нежели просто задекларировать несколько констант в ZCML, но глобальные константы вносят много проблем, неважно, определены они в Python, или в XML. Части вашего приложения предполагают их наличие с очень специфическими именами, а их типы нельзя проверить.
Как установить скин по умолчанию?
Используйте директиву browser:defaultSkin:
1 <browser:defaultSkin name="skinname" />
Для получения более подробной информации о скинах, обратитесь к документации.
Как зарегистрировать контент провайдер без использования менеджера вьюлетов?
Вам нужно создать и зарегистрировать простой адаптер для объекта, запроса и вида, который реализует интерфейс IContentProvider:
1 class LatestNews(object):
2
3 implements(IContentProvider)
4 adapts(Interface, IDefaultBrowserLayer, Interface)
5
6 def __init__(self, context, request, view):
7 self.context = context
8 self.request = request
9 self.__parent__ = view
10
11 def update(self):
12 pass
13
14 def render(self):
15 return 'Latest news'
В ZCML:
Тогда их можно использовать в TAL шаблонах следующим образом:
1 <div tal:content="provider latestNews" />
Также, вы, возможно, захотите передать через TAL некие параметры. Для получения информации о том, как это сделать, читайте документацию в zope.contentprovider. Если вы хотите привязать некий контент провайдер к скину, измените IDefaultBrowserLayer на ваш интерфейс скина.
Как подключить статическое содержимое?
Взгляните на директивы <resource> и <resourceDirectory> - они позволяют публиковать статические файлы посредством Zope. Обратитесь к документации по ресурсам браузера для получения более полной информации.
Доступны ли исходики сервера Webdav в !BlueBream?
Ссылка: http://mail.zope.org/pipermail/zope3-users/2006-September/004648.html
Да, вот ссылка на репозиторий: http://svn.zope.org/zope.webdav/trunk
Как использовать переопределения в сборщике в site.zcml для рецепта zc.zope3recipes:app?
Ссылка: http://mail.zope.org/pipermail/zope3-users/2007-April/006106.html
{{{highlight xml <includeOverrides package="myapp" file="overrides.zcml" /> }}}
Как сделать свой траверсинг в !BlueBream?
Обратитесь к этому блогу: http://mg.pov.lt/blog/zope3-custom-traversal.html
Программирование
Доступна ли документация по API онлайн?
Инфраструктура документации Zope3 обладает возможностью генерации html содержимого на лету. Это делает ее немножко медленной при просмотре на старых машинах.
Закешированный вариант документации (а поэтому быстрый) доступен на: http://apidoc.zope.org/++apidoc++/
Как вытянуть проект/пакет из SVN-репозитория?
Взгляните сюда: http://docs.zope.org/developer/noncommitter-svn.html
Как сделать апгрейд с более старого релиза?
Обновите versions.cfg и укажите URL версионного файла BlueBream нового релиза и запустите сборщик.
Нужно ли мне каждый раз перезагружать сервер при изменении файлов кода?
Нет, не нужно, если ві пользуетесь опцией --reload команды paster serve. То есть, запускать сервер следует так:
1 ./bin/paster serve --reload debug.ini
Мы рекомендуем писать автоматизированные тесты для просмотра эффекта, который произвели изменения. Вначале это кажется надоедливым, но, войдя в привычку, становится неотъемлимой и полезной частью процесса разработки.
Как автоматически создавать нужный объект при старте приложения?
http://mail.zope.org/pipermail/zope-dev/2007-December/030562.html
Вы можете сделать это подписываясь на событие IDatabaseOpenedWithRootEvent (из zope.app.appsetup)
Пример кода:
1 from zope.app.appsetup.interfaces import IDatabaseOpenedWithRootEvent
2 from zope.app.appsetup.bootstrap import getInformationFromEvent
3 import transaction
4
5 @adapter(IDatabaseOpenedWithRootEvent)
6 def create_my_container(event):
7 db, connection, root, root_folder = getInformationFromEvent(event)
8 if 'mycontainer' not in root_folder:
9 root_folder['mycontainer'] = MyContainer()
10 transaction.commit()
11 connection.close()
Потом зарегистрируйте подписчик в configure.zcml:
1 <subscriber handler="myapp.create_my_container" />
Как сделать валидацию двух или более полей одновременно?
Представьте себе простой пример: есть объект личность. Этот объект имеет атрибуты name, email и phone. Как реализовать правило валидации, которое определяет, существует ли email или phone, но необязательно оба.
Сначала сделаем вызываемый объект - либо простую функцию, либо вызываемый класс:
Теперь, определим интерфейс объекта следующим образом. Используйте функцию interface.invariant для установки инварианта:
Теперь используйте метод validateInvariants для валидации:
1 >>> class Person(object):
2 ... interface.implements(IPerson)
3 ...
4 ... name = None
5 ... email = None
6 ... phone = None
7 >>> jack = Person()
8 >>> jack.email = u"jack@some.address.com"
9 >>> IPerson.validateInvariants(jack)
10 >>> jill = Person()
11 >>> IPerson.validateInvariants(jill)
12 Traceback (most recent call last):
13 ...
14 Exception: At least one contact info is required
Как получить родителя location?
Для того, чтобы получить родителя объекта используйте zope.traversing.api.getParent(obj). Для получения списка родительских объектов - используйте zope.traversing.api.getParents(obj).
Как установить заголовок Content-Type HTTP-запроса?
Из IRC (http://zope3.pov.lt/irclogs/%23zope3-dev.2006-06-20.log.html):
Is there any way using the browser:page directive, that I can specify that the Type of a page rendered is not "text/html" but rather "application/vnd.mozilla.xul+xml"?
Используйте request.response.setHeader(‘content-type’, ...)
Как давать уникальные имена объектам при добавлении в контейнер?
Первое:
1 from zope.app.container.interfaces import INameChooser
Имя будет присвоено во время выполнения методов create и createAndAdd, вот пример:
1 def create(self, data):
2 mycontainer = MyObject()
3 mycontainer.value1 = data['value1']
4 anotherobj = AnotherObject()
5 anotherobj.anothervalue1 = data['anothervalue1']
6 namechooser = INameChooser(mycontainer)
7 name = chooser.chooseName('AnotherObj', anotherobj)
8 mycontainer[name] = anotherobj
9 return mycontainer
Как добавить каталог программно?
Ссылка: http://zopetic.googlecode.com/svn/trunk/src/browser/collectorform.py
Смотрите пример:
1 from zopetic.interfaces import ITicket
2 from zopetic.interfaces import ICollector
3 from zopetic.ticketcollector import Collector
4 from zope.app.intid.interfaces import IIntIds
5 from zope.app.intid import IntIds
6 from zope.component import getSiteManager
7 from zope.app.catalog.interfaces import ICatalog
8 from zope.app.catalog.catalog import Catalog
9 from zope.security.proxy import removeSecurityProxy
10 from zope.app.catalog.text import TextIndex
11
12 ...
13
14 def create(self, data):
15 collector = Collector()
16 collector.description = data['description']
17 return collector
18
19 def add(self, object):
20 ob = self.context.add(object)
21 sm = getSiteManager(ob)
22 rootfolder = ob.__parent__
23 cat = Catalog()
24 rootfolder['cat'] = cat
25 if sm.queryUtility(IIntIds) is None:
26 uid = IntIds()
27 rootfolder['uid'] = uid
28 sm.registerUtility(removeSecurityProxy(uid), IIntIds, '')
29 pass
30 sm.registerUtility(removeSecurityProxy(cat), ICatalog, 'cat')
31 cat['description'] = TextIndex('description', ITicket)
32 self._finished_add = True
33 return ob
Существует ли функция для получения URL Zope объекта?
Ссылка: http://zope3.pov.lt/irclogs/%23zope3-dev.2006-09-25.log.html
Используйте:
или:
1 zope.traversing.browser.absoluteURL
Как сортировать объекты из BTreeContainer?
Вопрос: Есть ли способ сортировки объектов, возвращаемых методом values() из zope.app.container.btree.BTreeContainer? Ссылка: http://zope3.pov.lt/irclogs/%23zope3-dev.2006-09-25.log.html
Используйте встроенную функцию sorted (доступна в Python 2.4 и выше)
1 sorted(my_btree.values())
Как получить параметры запроса в методе вида?
Ссылка: http://mail.zope.org/pipermail/zope3-users/2006-July/003876.html
MyPageView должен быть либо видом по умолчанию, который ассоциирован с объектом mypage или видом с именем mypage, который ассоциирован с объектов RootFolder.
Есть также альтернатива:
Как безопасно использовать Reportlab?
Ref: http://mail.zope.org/pipermail/zope3-users/2006-September/004583.html
Используйте мьютекс (mutex) (рекурсивный замок (lock) позволяет это сделать):
Почему мой объект не добавляется в журнал изменений (changelog)?
Ссылка: http://mail.zope.org/pipermail/zope3-users/2006-May/003392.html
Адаптирован ли он к IKeyReference? Если вы используете ZODB, наследования от Persistent будет достаточно.
Как добавлять новые интерфейсы в существующие компоненты/классы?
Ссылка: http://mail.zope.org/pipermail/zope3-users/2006-November/004918.html
Это можно сделать с помощью zcml:
Как получить запрос в обработчике события?
Вопрос: Как получить IRequest в обработчике событий (имею только context)? Ссылка: http://mail.zope.org/pipermail/zope3-users/2007-April/006051.html
1 import zope.security.management
2 import zope.security.interfaces
3 import zope.publisher.interfaces
4
5 def getRequest():
6 i = zope.security.management.getInteraction() # raises NoInteraction
7
8 for p in i.participations:
9 if zope.publisher.interfaces.IRequest.providedBy(p):
10 return p
11
12 raise RuntimeError('Could not find current request.')
Как создавать ленты RSS?
Обратитесь к http://kpug.zwiki.org/ZopeCreatingRSS (Взят из старого zope-cookbook.org)
Где взять документацию по синтаксису zope.conf?
Ссылка: http://zope3.pov.lt/irclogs/%23zope3-dev.2008-04-01.log.html
Обратитесь к schema.xml внутри яйца zope.app.appsetup. Этот xml файл укажет на остальную часть синтаксиса. Информация о теге <zodb> находится в яйце ZODB в файле component.xml
Как зарегистрировать браузерный ресурс в тесте?
Сначала создайте фабрику fileresource (или imageresourcefactory, или другой):
1 from zope.app.publisher.browser.fileresource import FileResourceFactory
2 from zope.security.checker import CheckerPublic
3 path = 'path/to/file.png'
4 registration_name = 'file.png'
5 factory = FileResourceFactory(path, CheckerPublic, name)
6 Then register it for your layer:
7
8 from zope.component import provideAdapter
9 provideAdapter(factory, (IYourLayer,), Interface, name)
Как получить зарегистрированный браузерный ресурс в тесте?
Ресурс - просто адаптер на запрос. Он может быть получен в любом контексте. Вы можете получить FileResource или DirectoryResource следующим образом:
1 getAdapter(request, name='file.png')
Если это папка ресурсов, то так:
1 getAdapter(request, name='img_dir')['foobar.png']
Тогда получите содержимое файла с помощью GET метода (хотя он не является частью какого-либо интерфейса):
1 getAdapter(request, name='img_dir')['foobar.png'].GET()
Как заменить стандартную страницу ошибки 404?
Зарегистрируйте вид для zope.publisher.interfaces.INotFound в своем слое. По умолчанию используется вид zope.app.exception.browser.notfound.NotFound. Существует эквивалент для пейджлетов (pagelets): z3c.layer.pagelet.browser.NotFoundPagelet
Как удалить целое дерево объектов?
Вы не можете управлять порядком удаления. Проблема в том, что определенные объекты удаляются слишком рано, в то время как они нужны другим объектам, особенно, если вы определили адаптеры к IObjectRemoved.
В общем случае нужно вручную создавать дерево зависимостей для удаления, и устанавливать порядок удаления самостоятельно. Одна из проблем, которую провоцируют события в том, что их порядок строго не определен.
Конфигурация и настройка
Как отключить выбор скина по URL?
FIXME: переопределить траверсинг пространства имен ++skin++?
Как установить z3c.traverser и zope.contentprovider?
'z3c.traverser и zope.contentprovider - вспомогательные пакеты с хорошими и чистыми док. тестами. Для их установки и запуска не нужно много времени, но эти пакеты не содержат примера конфигурации при добавлении их в проект. Из док. тестов становится ясным (и из ваших собственных, написанных во время тестирования собственного кода), что нужно настроить. Итак, для z3c.traverser: И для = Как объявить глобальные константы в ZCML? == Ссылка: http://mail.zope.org/pipermail/zope3-users/2006-September/004381.html Можно просто использовать директиву <utility>, и сгруппировать константы в логические участки. interfaces.py: config.py: configure.zcml: использование: Очевидно, что нужно проделать немного больше работы, нежели просто задекларировать несколько констант в ZCML, но глобальные константы вносят много проблем, неважно, определены они в Python, или в XML. Части вашего приложения предполагают их наличие с очень специфическими именами, а их типы нельзя проверить.
Вам нужно создать и зарегистрировать простой адаптер для объекта, запроса и вида, который реализует интерфейс IContentProvider: В ZCML: Тогда их можно использовать в TAL шаблонах следующим образом: Также, вы, возможно, захотите передать через TAL некие параметры. Для получения информации о том, как это сделать, читайте документацию в
Взгляните на директивы <resource> и <resourceDirectory> - они позволяют публиковать статические файлы посредством Zope. Обратитесь к документации по ресурсам браузера для получения более полной информации.
Ссылка: http://mail.zope.org/pipermail/zope3-users/2006-September/004648.html Да, вот ссылка на репозиторий: http://svn.zope.org/zope.webdav/trunk
Ссылка: http://mail.zope.org/pipermail/zope3-users/2007-April/006106.html {{{highlight xml <includeOverrides package="myapp" file="overrides.zcml" /> }}}
Обратитесь к этому блогу: http://mg.pov.lt/blog/zope3-custom-traversal.html
Добавьте следующее в свой apidoc.zcml или configure.zcml: Если он не показывается, добавьте следующее:
Используйте providedBy, который доступен для интерфейса, он возвращает True, если объект предоставляет интерфейс, и False, если нет. Пример:
Замените ‘package’ на имя вашего пакета.
Воспользуйтесь замечательным (и минималистичным) пакетом от Shane Hathaways’ - tcpwatch. Он записывает все данные, которые передаются между клиентом и сервером, их можно использовать при разработке тестов. Для записи сессии:
Ссылка: http://mail.zope.org/pipermail/zope3-users/2006-July/003830.html Пример:
Ссылка: http://mail.zope.org/pipermail/zope3-users/2006-August/004027.html ForbiddenAttribute - всегда (ВСЕГДА!!!) знак того, что пропущены настройки безопасности, или код пытается получить доступ туда, куда не должен обращаться. Если вы пытаетесь использовать известный метод, вы определенно не сделали настроек безопасности для него. Zope, по умолчанию, устанавливает отказ на доступ к атрибутам и методам, если нет явных настроек.
Вопрос: Я хочу добавить новую закладку в ZMI, чтобы получить возможность редактирования атрибутов неких объектов. Следовательно, я добавляю новый menuItem в меню zmi_views через ZCML: (MyClass - просто наследник Folder с дополнительными атрибутами). Проблема в следующем: новая вкладка всегда появляется на первом месте. Я бы хотел, чтобы она появлялась поле вкладки content, а не перед ней. Директива order не работает. Как мне перенастроить порядок отображения вкладок, чтобы моя вкладка находилась на 2-м месте? Реализация меню по умолчанию сортирует вкладки по интерфейсу, а в вашем варианте - вкладка наиболее специфическая для интерфейса. Обратитесь к
Когда вы компилируете Python, убедитесь, что вы установили библиотеку zlib (development).
Вот хорошо отформатированный IRC лог, объясняющий как Steve Alexander нашел некий баг; он дает много хороших советов об отслеживании ошибок: http://dev.zope.org/Members/spascoe/HowOneZope3BugWasFixed (Scott Pascoe) Ken Manheimer написал глубокий обзор интерактивной отладки в Zope через консоль Python. Хотя статья написана для Zope 2, много принципов остаются теми же, а некоторые техники актуальны для переноса на BlueBream. Вот ссылка: http://www.zope.org/Members/klm/ZopeDebugging Вот ‘Using the Zope Debugger’ из документации Zope3: http://svn.zope.org/*checkout*/Zope3/trunk/doc/DEBUG.txt
Когда вы пытаетесь шагнуть в такой код (библиотеки), то обнаружите, что файл исходника, на который ссылаетесь - неправильный. Более глубокая проверка показывает, что путь к исходнику содержит неверную часть, похожую на это: tmpXXXXX. Поправить это очень просто, но сначала почему это происходит: Когда вы устанавливаете яйца с помощью Для решения проблемы, просто удалите все должно сработать.
В файле Перезагрузите сервер (вам нужна консоль для взаимодействия с отладчиком): Теперь, когда запрос вызывает исключение, вы будете закинуты в последнюю точку отладки, в точку, где возникло исключение.
Вы можете использовать реализацию В BlueBream, blob хранилище настроено по умолчанию. Конфигурация Zope находится в blob-dir определяет папку, в которой будут хранится blob-поля.
Из отладочной оболочки вызовите функцию 1 <!-- register traverser for app -->
2 <view
3 for=".IMallApplication"
4 type="zope.publisher.interfaces.browser.IBrowserRequest"
5 provides="zope.publisher.interfaces.browser.IBrowserPublisher"
6 factory="z3c.traverser.browser.PluggableBrowserTraverser"
7 permission="zope.Public"
8 />
9
10 <!-- register traverser plugins -->
11 <!-- my own plugin -->
12 <subscriber
13 for=".IMallApplication
14 zope.publisher.interfaces.browser.IBrowserRequest"
15 provides="z3c.traverser.interfaces.ITraverserPlugin"
16 factory=".traverser.MallTraverserPlugin"
17 />
18 <!-- and traverser package container traverser -->
19 <subscriber
20 for=".IMallApplication
21 zope.publisher.interfaces.browser.IBrowserRequest"
22 provides="z3c.traverser.interfaces.ITraverserPlugin"
23 factory="z3c.traverser.traverser.ContainerTraverserPlugin"
24 />
1 <!-- register named adapter for menu provider -->
2 <adapter
3 provides="zope.contentprovider.interfaces.IContentProvider"
4 factory="tfws.menu.provider.MenuProvider"
5 name="tfws.menu"
6 />
7
8 <!-- this does the directlyProvides -->
9 <interface
10 interface="tfws.menu.provider.IMenu"
11 type="zope.contentprovider.interfaces.ITALNamespaceData"
12 />
1 <utility factory=".config.DatabaseLoginOptions" />
1 opts = getUtility(IDatabaseLoginOptions)
Как зарегистрировать контент провайдер без использования менеджера вьюлетов?
1 class LatestNews(object):
2
3 implements(IContentProvider)
4 adapts(Interface, IDefaultBrowserLayer, Interface)
5
6 def __init__(self, context, request, view):
7 self.context = context
8 self.request = request
9 self.__parent__ = view
10
11 def update(self):
12 pass
13
14 def render(self):
15 return 'Latest news'
1 <div tal:content="provider latestNews" />
Как подключить статическое содержимое?
Доступны ли исходики сервера Webdav в !BlueBream?
Как использовать переопределения в сборщике в site.zcml для рецепта zc.zope3recipes:app?
Как сделать свой траверсинг в !BlueBream?
Как сделать, чтобы мой проект, или другой, появился в APIDOC?
1 <apidoc:rootModule module=”myproject” />
1 <apidoc:moduleImport allow=”true” />
Как в коде определить, запущено ли приложение в режиме разработки (devmode) или нет?
Другое
Как проверить, предоставляет ли объект некоторый интерфейс?
Как запустить отдельный тест из пакета?
1 $ ./bin/test -vpu --dir package/tests test_this_module
Как записать сессию?
Как протестировать загрузку файлов с помощью zope.testbrowser?
1 >>> import StringIO
2 >>> myPhoto = StringIO.StringIO('my photo')
3 >>> control = user.getControl(name='photoForm.photo')
4 >>> fileControl = control.mech_control
5 >>> fileControl.add_file(myPhoto, filename='myPhoto.gif')
6 >>> user.getControl(name='photoForm.actions.add').click()
7 >>> imgTag =
8 'src="http://localhost/++skin++Application/000001/0001/1/photo"'
9 >>> imgTag in user.contents
10 True
Почему я получаю !ForbiddenAttribute исключения/ошибки?
Атрибут order отсутствует в директиве browser:menuItem?
Почему при запуске выдается ошибка импорта zlib?
Я получаю ошибку Server Error, когда делаю то, что должно работать. Как сделать отладку?
Не вижу исходников при отладке кода в яйцах
1 find . -name "*.pyc" | xargs rm
Каким образом я могу получить последнее сообщение отладчика, когда запрос вызывает исключение?
1 ./bin/paster serve debug.ini
Как использовать ZODB blob?
Как очистить историю (упаковать) ZODB?