|
View:
New views
6 Messages
—
Rating Filter:
Alert me
|
|
|
the beginnings of megrok.feedsI have started writing a "megrok.feeds" package that will let you easily
turn container-like objects into Atom and RSS feeds, and objects in your containers into items inside of those feeds. (Should I call this "megrok.syndication" instead? It takes longer to type.) You can look inside the Zope repository to see what I have done so far. Some of you might recall that I have differences with Derek Richardson, the author of "vice.outbound", about how his work should be extended to create "megrok.feeds". I had initally imagined that, for each Grok container which could support a feed, the Grok programmer would write something like: class FolderFeed(megrok.feeds.AtomFeed): grok.name('atom') grok.context('Folder') def update(self): self.title = Folder %r Feed' % self.name self.description = 'Recent changes to folder %r' % self.name ... And I would write a grokker that did roughly what a grok.View grokker does, except that there would be no choice of template (an "atom.pt" from "megrok.feeds" would be used automatically), and there might be a bit more logic under the covers to gather any extra information that the feed needed. <SIDE QUESTION> Why does the "ViewGrokker" in Grok's "meta.py" call "provideAdapter", which I think is a global registration command, when registering a View? Shouldn't it instead register the view as a local adapter inside of its particular Grok site? Imagine that I have a Python module that provides "Foo" objects, and I instantiate two different Grok apps in my database that both use "Foo" objects; to be concrete, imagine that "app1" defines a "/one" view on a "Foo" object and that "app2" defines a "/two" view. Since the grokker defines each view globally, then it seems that not only would these two desired URLs work: http://localhost:8080/app1/foo/one http://localhost:8080/app2/foo/two but also the two unwanted URLs: http://localhost:8080/app1/foo/two http://localhost:8080/app2/foo/one because the global registrations would make each application's views magically appear over in the other application? </SIDE QUESTION> Derek instead advocated a different approach. First, the application designer would define, say, "/atom" as the way to view any feed-able container as an Atom feed. Second, they would then write an adapter for each kind of container that they wanted turned into a feed. The result in Grok code might look like: class Atom(megrok.feeds.AtomFeed): grok.name('atom') class FolderFeed(megrok.feeds.Feed): grok.context('Folder') def update(self): self.title = Folder %r Feed' % self.name self.description = 'Recent changes to folder %r' % self.name ... After thinking about Derek's scheme for two or three weeks, I realized that it did have at least one nice feature: it forced programmers to use the same name for feeds across their whole site. With my example scheme shown up above, if a programmer was not careful then they could wind up with all sorts of names for a given kind of feed on a given site ('/atom', '/Atom', '/feed', etcetera) - and sites whose feed names are inconsistent are really annoying. Whereas with Derek's scheme, they just say once "Atom feeds are located at /atom for all my containers", and don't have to repeat the name over and over again for each container that they describe how to feed-ify. So because I like the idea of consistency, I tried doing things Derek's way; you can take a look at the Grokkers here: http://svn.zope.org/megrok.feeds/trunk/src/megrok/feeds/meta.py?rev=88618&view=auto As you can see, per Derek's design, there are three registrations that have to get done before an Atom feed can work; for example, for the classes defined above, this would look like: - The feed view itself has to be registered as a multi-adapter: (factory=Atom, adapts=(IFeedable, IBrowserRequest), name='atom') - The adapter that turns the container into the feed is a single-adapter: (factory=FolderFeed, adapts=(Feed,), provides=IFeed) - The container type itself has to be marked as feedable: classImplements(Folder, IFeedable) That way, when you say 'myfolder/atom', the "Atom" view will get activated because 'myfolder' will be marked as "IFeedable", then it will try to adapt its context to IFeed, and will succeed because the adapter to IFeed exists. In my recent exchange with Derek, I objected to this scheme because it seemed odd to have to have so many interfaces just to get a single view working. Again, I'm rethinking that, because it would be so useful to corral Grok developers into naming only once what they will call each kind of feed on their site. My big issue at the moment, though, which I guess is reflected in the big "SIDE QUESTION" up above, is that I have no idea how to make any of this local. If the developer runs two Grok apps inside of a single Zope instance, and one app made the decision that "/atom" is how you ask for an Atom feed but the other app named its syndication links "/feed" instead, how do I keep the results of these decisions "local" to each app? If "/atom" is registered sitewide through a "provideAdapter()" call, then I don't see at all how it can affect only the current Grok app and not others inside of the same instance. I know it's odd to hear me ask about running multiple Grok apps in the same instance, because I've complained before that it makes little sense and that the extra "/app" part of every Grok URL is just an annoyance. But if we're going to support them, then I need to understand how we keep them separate from each other's active views; and, at the moment, I don't see how this is done. -- Brandon Craig Rhodes brandon@... http://rhodesmill.org/brandon _______________________________________________ Grok-dev mailing list Grok-dev@... http://mail.zope.org/mailman/listinfo/grok-dev |
|
|
Re: the beginnings of megrok.feedsOn Sat, 2008-07-19 at 17:36 -0400, Brandon Craig Rhodes wrote:
> <SIDE QUESTION> > Why does the "ViewGrokker" in Grok's "meta.py" call "provideAdapter", > which I think is a global registration command, when registering a > View? Shouldn't it instead register the view as a local adapter inside > of its particular Grok site? Imagine that I have a Python module that > provides "Foo" objects, and I instantiate two different Grok apps in my > database that both use "Foo" objects; to be concrete, imagine that > "app1" defines a "/one" view on a "Foo" object and that "app2" defines > a "/two" view. Since the grokker defines each view globally, then it > seems that not only would these two desired URLs work: > > http://localhost:8080/app1/foo/one > http://localhost:8080/app2/foo/two > > but also the two unwanted URLs: > > http://localhost:8080/app1/foo/two > http://localhost:8080/app2/foo/one > > because the global registrations would make each application's views > magically appear over in the other application? > </SIDE QUESTION> Non-persistent configuration is a good thing if it works for you. Maintaining component registration in the database can be a huge drawback WRT to code restructuring/deprecation. -- Christian Theune · ct@... gocept gmbh & co. kg · forsterstraße 29 · 06112 halle (saale) · germany http://gocept.com · tel +49 345 1229889 7 · fax +49 345 1229889 1 Zope and Plone consulting and development _______________________________________________ Grok-dev mailing list Grok-dev@... http://mail.zope.org/mailman/listinfo/grok-dev |
|
|
Re: the beginnings of megrok.feedsChristian Theune <ct@...> writes:
> On Sat, 2008-07-19 at 17:36 -0400, Brandon Craig Rhodes wrote: >> Why does the "ViewGrokker" ... call "provideAdapter", which ... is >> a global registration command...? Shouldn't it instead register the >> view as a local adapter inside of its particular Grok site? Imagine >> that ... I instantiate two different Grok apps in my database that >> both use "Foo" objects ... it seems that ... the global >> registrations would make each application's views magically appear >> over in the other application? > > Only if your 'Foo' objects really refer to the same class objects. Yes, which is precisely what I am imaging; that two Grok apps, for example, might both provide views for a single class, like the standard library class "email.Message". > Non-persistent configuration is a good thing if it works for you. > Maintaining component registration in the database can be a huge > drawback WRT to code restructuring/deprecation. Thank you, Christian; while puzzling over why Grok uses global registrations for views that should obviously only exist beneath each particular Grok app, I forgot that local adapters are currently implemented using the ZODB. It is now clear to me that I need to make some proposals. 1. Grok Local Adapters Should Not Live In The Database ------------------------------------------------------ I am beginning to think it is entirely misguided that Grok attaches local adapters to Application objects through the database. This seems to have only bad consequences. Instead, when Grok code declares a local adapter and asks that it be installed on a Grok Site, this should be something done in RAM, at runtime, as part of grokking. Zope traversal should be extended, if it does not already support the feature directly, so that local adapters can get activated as it traverses past an object of a particular class. In other words, if I create a local adapter "X" in my "EmailSite" Grok Application, then at grokking time some Zope registry (which we might have to create) mapping classes to local adapters should get the registration: "EmailSite class objects, when traversed, activate local adapter X" Then, when Zope is traversing into our App objects, the correct adapters get activated. Beautiful! This would have the magnificent property that when someone added a new local adapter to their code and restarted, it would immediately start working without their having to delete and re-create their Application object; and, when someone removed a local adapter, it would immediately start working. In Grok, we declare things in code. They should stay there. 2. We Should Rename LocalAdapter to PersistentLocalAdapter ---------------------------------------------------------- We should keep the current local adapters around; I am not suggest that we delete or remove them! Someone might have found them useful, and, if so, they should still be able to use them. But they should have the word "Persistent" attached to them so that anyone crazy enough to use them gets a big, obvious signal that unlike most of the things that they create in Grok - like Views and Viewlets - PersistentLocalAdapters will *not* simply work because they exist in the code. The word "Persistent" will be a hint that this is a crazy hybrid concept that straddles the world of code and the world of storage, and that has to exist in *both* places (both in your code, and also in the database with your application) before it will work. 3. Views and Viewlets Should Become New-Style Local Adapters ------------------------------------------------------------ Once we have working the concept of lightweight, non-persisted, traversal-activated adapters working, then all normal Grok adapters like Views and Viewlets should become new-style local adapters. If your Grok app defines an "EmailIndex" view that renders an "email.Message" object for your site, then the "EmailIndex" should only be active and available when a user is actually browsing beneath your Grok app. Other apps should not have the view available, since this makes it impossible to install several Grok apps inside of a single ZODB instance without their views bleeding over and becoming available inside each other. This will require a small bit of code so that the grokkers will "see" where your Application object is inside of your Grok application code base, so that they can make all of your Views these new-style local adapters. It might now become an error (I'm not sure it is right now?) to have two grok.Application objects inside of a Grok application; or we might allow a single code base to provide multiple Applications so long as the user could signal which views went with which others. Anyway, remember that I have always been a bit skeptical of why we create Application instances in the first place instead of a Grok Application just being always the root of its site; but if we are going to support multiple Grok apps in a single ZODB, as we do today, then the above steps seem to me quite necessary to stop them from trampling all over each other. ME GROK WANT APPLICATION ORTHOGONALITY :-) -- Brandon Craig Rhodes brandon@... http://rhodesmill.org/brandon _______________________________________________ Grok-dev mailing list Grok-dev@... http://mail.zope.org/mailman/listinfo/grok-dev |
|
|
Re: the beginnings of megrok.feedsOn Jul 21, 2008, at 2:27 PM, Brandon Craig Rhodes wrote:
> Christian Theune <ct@...> writes: >> On Sat, 2008-07-19 at 17:36 -0400, Brandon Craig Rhodes wrote: > >>> Non-persistent configuration is a good thing if it works for you. >> Maintaining component registration in the database can be a huge >> drawback WRT to code restructuring/deprecation. > > Thank you, Christian; while puzzling over why Grok uses global > registrations for views that should obviously only exist beneath each > particular Grok app, I forgot that local adapters are currently > implemented using the ZODB. > > It is now clear to me that I need to make some proposals. > > 1. Grok Local Adapters Should Not Live In The Database > ------------------------------------------------------ > > I am beginning to think it is entirely misguided that Grok attaches > local adapters to Application objects through the database. This > seems > to have only bad consequences. I think it's more common this happens for utilities. But I agree that grok should not persist utilities or adapters if there are ways not to do that. I don't have any experience of z3c.baseregistry, but I think it allows you to add local utilities with zcml. http://svn.zope.org/z3c.baseregistry/trunk/src/z3c/baseregistry/README.txt?rev=70114&view=auto snip... > Anyway, remember that I have always been a bit skeptical of why we > create Application instances in the first place instead of a Grok > Application just being always the root of its site I agree the use of application is a bit weird. It's been discussed before, but it didn't look anyone agreed with me. As it is now, an application is not necessarily the root of the website. Have no idea why anyone would want to nest grok.Application objects. It just makes stuff more complicated, at least educationally. But I'm not sure this has to be resolved with traversers. The registries and their hierarchy will always be the same on every traversal. /Tim _______________________________________________ Grok-dev mailing list Grok-dev@... http://mail.zope.org/mailman/listinfo/grok-dev |
|
|
Re: the beginnings of megrok.feedsChristian Theune <ct@...> writes:
> On Sat, 2008-07-19 at 17:36 -0400, Brandon Craig Rhodes wrote: > >> Imagine that ... I instantiate two different Grok apps in my >> database that both use "Foo" objects ... [will] global >> registrations ... make each application's views magically appear >> over in the other application? > > Only if your 'Foo' objects really refer to the same class objects. At the very least, think about all of those Viewlets and macros that seem to get attached to Python classes like "Interface" these days! If three Grok applications were installed in a single site that all had views built atop "Interface", then I think that under the current scheme (which, as outlined in a recent email, I would like to change) there would be no way from stopping people from trying to invoke each application's views atop objects from the other applications. -- Brandon Craig Rhodes brandon@... http://rhodesmill.org/brandon _______________________________________________ Grok-dev mailing list Grok-dev@... http://mail.zope.org/mailman/listinfo/grok-dev |
|
|
local but-non-persistent registration of componentsHey,
I saw that a discussion on megrok.feeds evolved towards a discussion of local-but-non-persistent registration of components such as views, adapters and utilities. I'd be nice to have this feature. I think we have two areas of discussion: * how to actually do it technically - how do we make sure these locally registered components are correctly known as 'registered' in a site when starting up the application? * what a nice syntax for this might be to make this work for the various kinds of components (or what the impact would be to make grok do this automatically in some cases) Regards, Martijn _______________________________________________ Grok-dev mailing list Grok-dev@... http://mail.zope.org/mailman/listinfo/grok-dev |
| Free Forum Powered by Nabble | Forum Help |