yeah, if you want to nest your URLs arbitrarily deep and you want human-readable URLs traversal might be a good choice... that need wasn't clear from your original description.

in any event, i tried to point you in the right direction. hopefully it was useful. :)

-r


On 06/15/2011 03:07 AM, toudi wrote:
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.

Reply via email to