2008-04-04

ng.base.form

Andrey Orlov  2008-04-04 22:32

Базовый класс формы, составляемой TTW. Сейчас в заключительной стадии разработки.

Краткое описание пакета ng.base.form

Краткое описание пакета ng.base.form

Пакет разработан как базовый объект, позволяющий создать форму через веб-интерфейс. От этого базового объекта порождены ng.app.registry и ng.app.mailform.

Общие рекомендации к реализации

Пакет состоит из контейнера, в который могут вкладываться объекты, соответствующие полям форм, набора классов, соответствующих разновидностями полей форм и специальной страницы-редактора. В настоящее время, точный прототип того, что должно получится существует в продукте ng.app.registry, все что надо сделать это:

  1. Аккуратно вырезать из ng.app.registry все вышеописанное, переименовать классы и сохранить в новом продукте;
  2. Вместо существующих там в настоящее время классов RegistryInt, RegistryTextLine, которые являются тупым хранилищем значения для данного поля, следует создать классы FormInt, FormTextLine которые предоставляют творчески переработанные интерфейсе zope.schema.IInt, zope.schema.ITextLine, так, что бы созданный объект можно было настроить так, что бы фабрика (атрибут factory) могла быть проинициализирована этими атрибутами наиболее точным образом. Место текущего атрибута data займет при этом атрибут default %).
  3. Переработать форму browser/registryedit, так что бы она работала с новыми описателями для формы.
  4. Породить ng.app.registry от нового базового класса, стерев оттуда текущую реализацию.

Далее можно заняться созданием почтовой формы :).

Дополнительные рекомендации к реализации

Итак про грабли. Ну я не буду рассказывать что ты скопировала слишком много: я всё, что не относилось непосредственно к формочке - выкинул.

Структура исходников была у тебя немножко на скорую руку сделана, все свалено в один файл, так делать лучше не надо никогда Это я тоже поправил

Базовый класс я написал для всех form-item, это ты можешь увидеть. Он не очень удачный, но пока сойдет

Теперь про грабли, их было трое:

1. часть полей в интерфейсах типа IInt были Field, и соответственно виджета для этих полей нету. Их пришлось в интерфейсах поперекрывать подходящими полями

2 не все поля интерфейсов IField (в частности поле order) имеют шансы появится в формах добавлния соответствующих formitem, единственный способ борьбы, который я нашел, это перечислить поля в поле fields форм, как это я и сделал. После этого формитемы стали добавлятся и редактироваться

3 пропала атрибут data и вместо него по заданию нужно использовать атрибут default, что я и сделал

Теперь твои дальнейшие планы Они все в основном сводятся к переработке генератора форм. Это то, что делается вот тут:

formedit.py

schema = InterfaceClass('IGeneredForm',(Interface,),
  dict( [ (x,removeSecurityProxy(y.factory)(title=unicode(x),default=y.default)) for x,y in context.ite
  )

Не очень понятно что это, но на самом деле это динамически генерируется схема для формы. Генеруется она по поля item-ов сейчас оставлена старая схема, т.е. реально задействуется только title и default А в качестве фабирки используется то, что прошито в коде.

РЕально придется вот это место:

y.factory(title=unicode(x),default=y.default)

перенести внутрь классов форм-итемов, так как у каждого форм-итема своя фабрика и, в общем случае, свой набор атрибутов. И эта "свойскость" будет только возрастать, когда мы воспользуемся такими полями как ng.schema.regexptextline :) Так что в каждый класс вместо существующего там присваивания factory=<чтототам> Надо прописать

def factory(self) :
  return <чтототам>( атрибуты, набранные из self в соответствии со схемой интерфейса)

Значения пока останутся там же, хотя интегрируется с двумя возможными применениями это плохо. Но, видимо, мы это изменим :), воспользовавшись адаптерами.

Ры: Спасибо за прототип.

Способ привязки формы к другим компонентам

Привязка формы к другим компонентам (в частности - к реестру) выполняется за счет реализации специального адаптера к интерфейсу IFormSave.

Интерфейс IFormSave
Интерфейс IFormSave предоставляет единственный метод do(), принимающий в качестве аргумента словарь значений.

Адаптер этого интерфейса может, например, сохранять все значения там, где его сейчас сохраняет setData.

План работы

  1. Выкинуть из ng.app.registry весь код, связанный с контейнером и формамами;
  2. В ng.base.form определить интерфейс IFormSave
  3. В setData вместо существующего сейчас кода вставить приведение контекста к IFormSave, и если приведение удачно - вызов метода do(), если приведение вызывает исключение - ничего не делаем.
  4. Наследовать ng.app.registry от ng.base.form
  5. Пишем (в ng.app.registry) адаптер IRegistry к IFormSave, в который фактически переносим код, существоваший до п. 3 в setData;
  6. Проверяем работоспособность новой версии реестра.

Ссылки на эту статью:

План работы для АнтЕл Astoon
Официальный сайт Zope3 Московская группа изучения реактивного движения The Dream Bot Site noooxml