Gary Poster wrote: > The use case we are trying to address with the iterable source > interface is that we want to be able to distinguish between sources > that should be searched, and those that should be displayed as explicit > choices. I'll call these 'searchable' and 'showable' sources and > widgets below. I'll discuss a few of the possible approaches to the > problem. > > One way is to register searchable widgets for all source fields. If > you want a showable widget for a given source, you need to confirm that > the source supports __iter__ and then register a showable widget for > the combinations of source plus each field type that uses the source > (i.e., Choice, Tuple, Set, etc.). That's a bit heavy when you have a > reasonable number of these sources in your application. You could also > do this kind of story with a custom widget for each form, but that > would be even more impractical and annoying with heavy source usage. > > Another way would be to have an interface that marks a source as > 'showable'. You could then register searchable widgets for standard, > non-showable source fields; and showable widgets for fields marked as > showable. This is convenient. If you make the decision actually in > the software, you are making the decision at the wrong level (it is > configuration), but if you declare the showable interface on the source > with zcml, it is closer to being in the right location. It still feels > problematic though: what if the source is used for display in multiple > formats--HTML vs. rich client, for instance? What if a source has > variable options during the lifetime of the application, and sometimes > is appropriate to be shown as a searchable, and sometimes as a showable?
This is the way we solved this issue in Launchpad. We make our vocabularies that should be searchable implement IHugeVocabulary, which also has a search method that is used by a custom widget (currently a popup window that lets you interactively search and populates the real control in the parent window using Javascript, but this is really a placeholder until we get something inline going). This custom widget is used for all IHugeVocabularies. This is good, because it means the UI is consisent between our development boxes (with little sample data, eg. 50 people) and the staging and production boxes (real data, eg. over 40000 people). It also means that our page tests are testing the UI that will exist on production rather than something quite different. > The last way I'll discuss is the way we chose, but did not follow > through on completely. In this one, you mark the source as iterable in > the software, and make iterable sources also specify a len. In this > case, you *can* (but we don't yet) register an intermediary adapter for > these iterable sources. If the len is beneath whatever limit you > desire (for the given kind of request), you can return a showable > widget, and otherwise return a searchable widget. Note that if a > source is iterable but is too big to quickly calculate its length, that > almost certainly is going to suggest a searchable widget, rather than a > showable widget. I can see this being useful as a safety net for when a developer forgets to use a marker interface to say 'this should be searchable' (and if we were implementing it, if this safety net kicked in a warning would be emitted). So if you have a Source that should always be searchable, it would just implement ISource. I can't think of any use cases for needing to iterate over one of these. And if you have a Source that can be iterated over or rendered as a select or list of radio buttons, you would implement IIterableSource. I can't think of any use cases for this case not being able to calculate the length. So the only thing I think needs changing here is the documentation suggesting returning maxint from __len__. It was more problematic in the Vocabulary code, because IVocabulary extended IIterableVocabulary, forcing all vocabularies to implement that interface. Sources give us the opportunity to reverse and fix that, making IIterableSource extend ISource. The docstrings don't make it clear what an ISourceQueriables is supposed to achieve, how one is constructed or how it is to be used. I would imagine that the interfaces should look like: class ISourceItem(Interface): key = TextLine('Unique key', required=True) title = TextLine('Descriptive text to display to users. Plain text.') value = Attribute('Object represented by this ISourceItem') class ISource(Interface): context = Attribute( "context the source is bound to. Generally an IChoiceField" ) def __contains__(key): """Returns true if the key exists in this source""" def __getitem__(key): """Returns the ISourceItem for this key""" def search(query): """Return a sequence of ISourceItem matching the given query. query is a Unicode string or None. The meaning of this query is ISource specific. """ class IIterableSource(ISource): def __iter__(): """Iterate over all ISourceItems""" # This method needs to be renamed count or size if it needs # to support returning 'length unknown' def __len__(): """Number of ISourceItems""" The default widget for an ISource would be a simple text entry where the user enters the key. The default widget for an IIterableSource would be a <select> of <option value="key">title</option>, with a fallback to the default ISource widget if __len__() > 200 (or some arbitrary constant). I wouldn't like to use the title as the key, because the title might be changed where as keys should be unchanging (or at least more so). I think the ISourceItem is important, as it allows people to extend what is being returned by their sources. In particular, we would have IIterableSource sources that return IRichSourceItem which also provides a snippet() method or view. This would provide an XHTML fragment which would be used to render a list of radio buttons or check boxes with markup in the descriptive text. -- Stuart Bishop <[EMAIL PROTECTED]> http://www.stuartbishop.net/
signature.asc
Description: OpenPGP digital signature
_______________________________________________ Zope3-dev mailing list Zope3-dev@zope.org Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com