I did read 'Much ado about traversal" and it was one of the reasons i
decided to go that way. Let me give you a quick example:
Let's assume, that in e-commerce application we have a place for
logged in user. He can access it via:
/account
So far so good. Now, this account panel should have some modules.
Let's say, that it has a 'shop' module which gives some basic
information about user's shop:
/account/shop
now we can have another submodule, let's say about products:
/account/shop/products
and so on.
When using URL matching approach we would need to define those routes
manually:
config.add_route("/account", "views.account")
config.add_route("/account/shop", "views.account.shop")
and so on (because we don't know how nested the modules can be i
believe we cannot regexp it)
But it isn't very flexible - an ideal approach for me would be the
sittuation when somebody could somehow "create" url matches and / or
traversal contexts inside the actual modules. So for example:
#/views/account/account.py
config.add_route("/account/ ... ")
#/views/account/shop.py
and so on.
however, when using URL matching we still must define those routes. I
was hoping to use traversal in order to do something like this:
#views/account/account.py
root.add_child("account")
#views/account/shop.py
root["account"].add_child("shop")
#views/account/shop/products.py
root["account"]["shop"].add_child("products")
and so on. (however i believe i cannot have both shop.py and a folder
named "shop", but that's just an example ;) )
Another classic scenario is an admin backend for application - it also
has many submodules.
And i used a dict because i was trying to follow the docs section
about Resources - there's an example there:
class Resource(dict):
pass
however when i used it like this i got some error about a dict not
being callable or hashable ( i don't know for sure right now because i
don't have the code ). Then i read about locations and the need of
using __name__ and __parent__ in resources therefore i created an
object.
The wiki tutorial had another implementation of resources, however it
used ZODB which i was not going to use ( in pylons i used
sqlalchemy ).
Also, a wiki tutorial didn't quite fit into my problem because (i
don't know the technical term for that) wiki uses 'flat' urls ( i.e. /
wiki/<pagename>/action ).
On 15 Cze, 02:30, Rob Miller <[email protected]> wrote:
> /me dons his "traversal explainer" cape and mask...
>
> first, and foremost, i don't think you actually need or want traversal here.
> you say you read the "traversal" and "resources" chapters of the docs, but did
> you read the "much ado about traversal" piece (http://tinyurl.com/4exxjvw)?
> especially the "use cases" section, where it describes the cases where
> traversal is a better choice than URL matching. your use case meets none of
> those criteria, AFAICT, so you probably don't want to use traversal at all.
> i'm pretty sure you CAN still use config.scan to register your views even w/o
> traversal, so i'm not entirely sure what the problem is there.
>
> but, just for the fun of it, let's say traversal was a good idea. what are
> you doing wrong? there are a few things that seem a bit wonky in the code
> (e.g. the fact that your resource class inherits from dict but then doesn't
> act like a dict, delegating to a contained dictionary attribute instead), but
> i'll ignore those for now. the main problem seems to be that you're trying to
> use specific instances as your "context", when really context is better suited
> to using types.
>
> something like this is probably closer to what you want (totally untested, use
> at your own risk, this code may steal your car and eat your cookies, etc.):
>
> class Resource(object):
> def __init__(self, name=None, parent=None):
> self.__name__ = name
> self.__parent__ = parent
> self.children = {}
>
> def add_child(self, name, klass=None, **kw):
> if klass is None:
> child = Resource(name, self)
> else:
> child = klass(name, self, **kw)
> self.children[name] = child
>
> def __getitem__(self, name):
> return self.children[name]
>
> class Task(Resource):
> pass
>
> then you'll need to instantiate some of these things:
>
> root = Resource('root')
> root.add_child('some_task', Task)
> root.add_child('another_task', Task)
>
> now you can register a view on Task objects like this:
>
> @view_config(name="method", context=Task)
> def task_method(request):
> task = request.context
> ... do something w/ your task object ...
> return Response(...)
>
> if this is all wired up correctly then the following paths should resolve to
> your view:
>
> /some_task/method
> /another_task/method
>
> now it might be possible to achieve the same thing by using a specific
> instance as your context rather than a class... the view config docs don't say
> anything about that, though, and i've never done it; i'd find it a bit
> confusing.
>
> hope this helps,
>
> -r
>
> On 06/14/2011 01:58 PM, toudi wrote:
>
>
>
>
>
>
>
> > hello.
>
> > before i begin i would like to say, that i have read both 'Traversal'
> > and 'Resources' chapters from pyramid docs. I also read this thread ->
> >http://groups.google.com/group/pylons-devel/browse_thread/thread/a8d4...
> > which is a similar problem i have, but i still cannot wrap my mind
> > around traversal. However, i think it's the best approach for me,
> > because of it's config.scan() capabilities. I also have a background
> > in pylons, which i was using without any problems.
>
> > So - to keep my long story short, i am trying to implement a fairly
> > simplistic application (task / bugtracker) in order to learn pyramid.
> > Here are the models:
>
> > User - a developer
> > Task - a Bug, that can have one developer and many comments.
> > Comment - a Task comment.
>
> > i have named my project 'flyswatter', therefore:
>
> > #flyswatter/__init__.py
>
> > ...
> > config = Configurator(settings=settings)
> > config.add_static_view('static', 'flyswatter:static')
> > config.scan(".views")
> > ...
>
> > #flyswatter/resources.py
>
> > class Resource(dict, object):
> > def __init__(self, name = None, parent = None):
> > self.__name__ = name
> > self.__parent__ = parent
> > self.children = {}
>
> > def add_child(self, name):
> > self.children[name] = Resource(name = name, parent = self)
>
> > def __getitem__(self, name):
> > return self.children.get(name)
>
> > root = Resource()
>
> > now - onto my problem. I would like to use config.scan() and traversal
> > in order to map url's to the views. my view directory structure looks
> > like this:
>
> > #flyswatter/flyswatter/views
> > __init__.py
> > default.py
> > task.py
> > admin
> > admin/__init__.py
> > admin/foo.py
>
> > The only way i managed to combine the traversal with views mapping is
> > like this:
>
> > #views/default.py
> > from flyswatter.resources import root
>
> > @view_config(context = root)
> > def index(request):
> > return Response('root::index')
>
> > @view_config(name="method", context = root)
> > def method(self):
> > return Response('root::method')
>
> > so far so good - url's "/" and "/method" are correctly mapped.
>
> > #views/task.py
> > from flyswatter.resources import root, Resource
>
> > root.add_child("task")
> > root["task"].add_child("method")
>
> > @view_config(name="task_index", context = root["task"])
> > def index(request):
> > return Response('task::index')
>
> > @view_config(name="task_method", context=root["task"])
> > def method(request):
> > return Response('task::method')
>
> > not so good - in order to access task.method i need to type the url /
> > task_method ( instead of /task/method ). I also cannot access
> > task.index by visiting /task - i need to use /task_index.
> > I tried to use "/task/method" as a name in @view_config but this
> > didn't seem to make any difference.
>
> > I think i'm pretty close to the desired result, however i am 100% sure
> > i am missing some crucial bit of information on understanding how
> > traversal / view mapping work. Could some direct me in a right way,
> > please? :)
>
> > best regards,
> > toudi.
>
> > p.s. sorry if my code looks ugly, i am still learning.. :)
> > p.p.s. i don't want to use view handlers - because ( unless i'm
> > mistaken ) i need to explicitly register the view classes one by one
> > in __init__.py. The config.scan() approach seems like a lot easier
> > ( for instance for creating additional modules for the admin panel
> > without modyfing flyswatter/__init__.py )
--
You received this message because you are subscribed to the Google Groups
"pylons-discuss" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/pylons-discuss?hl=en.