3

I'm trying to build a Friendly URL lookup method in GAE and Python. Have anyone done this?

I've got it working but it feels VERY shaky. How it works is that it takes the path (let's say /foo/bar/) and splits it to a list. Takes the last element in the list and query the database for a match. Now comes some headaches.

If there is more that one 'bar' since there could be another 'bar' but under a different page, how to tell them apart? As of now, my solution is to iterate over the result of 'bar' and look at a reference property to it's parent page. The parent 'foo' could also occur more then once so now we have to iterate over that to. It isn't hard to see that this cloud easily add up to a large number of for loops.

Just to make it a bit worse one page could be able in more then one language and the url need to match the give language.

My current datastore setup is this:

## Class to store pages.
class Pages(db.Model):
    name = db.StringProperty()
    ## Some more properties for storing content
    parentKey = db.SelfReferenceProperty()

## Class to store friendly url path segments
class UrlProvider(db.Model):
    name = db.StringProperty()
    path = db.StringProperty()
    langCode = db.StringProperty()
    page = db.ReferenceProperty(Pages)

And to fetch a page using firendly url:

pageFromUrl = UrlProvider.gql('WHERE path = :path AND langCode = :lang', path = path, lang = templateObject.lang).fetch(100)

for pageUrl in pageFromUrl:
    parentFromUrl = UrlProvider.gql('WHERE page = :page AND langCode = :lang', page = pageUrl.page.parentKey, lang = templateObject.lang).fetch(100)
    for parentUrl in parentFromUrl:
        if parentUrl.path == templateObject.path[-2]:
            templateObject.url = parentUrl.path + '/' + path
            page = pageUrl.page

What it does is, it fetches from UrlProvider everything that matches the last item in the templateObject.path list. Iterates over it and fetches all parents and trying to match it.

As of now it only works for one root page and one subpage. I don't know how to make it more dynamic and support multiple levels.

Have anyone written their own or have any good suggestions?

fredrik
  • 17,537
  • 9
  • 51
  • 71
  • possible duplicate of [Pretty URLs in Google App Engine / URL Rewriting](http://stackoverflow.com/questions/2297056/pretty-urls-in-google-app-engine-url-rewriting) – ceejayoz May 26 '10 at 20:44
  • Unfortunately no. My question is more about how to store and get data properly then rather how to get the url. – fredrik May 26 '10 at 21:01
  • What exactly is the objective here? If you're just doing direct lookups, why not just make the key name the URL path? – Nick Johnson May 26 '10 at 21:49
  • @Nick: Could you explain a bit more what you mean? What I'm trying to do is to map a URL segment to a page in the datastore. Since a URL segment isn't unique I can't figure out how to get all pages that is part of the URL without a costly number of for loops. – fredrik May 27 '10 at 08:00

2 Answers2

1

http://code.google.com/appengine/docs/python/tools/webapp/running.html#URL_Mappings

Check out the section that says url mappings

this is complete code but I hope you get the idea

this is my request handler parama = my first param, paramb = my second param

class testPath(webapp.RequestHandler): def get(self,parama,paramb): # notice the 2 extra params, not just self self.response.out.write(parama) self.response.out.write(paramb)

.... # below you see i mapped anything that request "/test// notice the "r" before the 'urlmapping'

application = webapp.WSGIApplication([ (r'/test/(.)/(.)', testPath), ('/logout', LogoutHandler) ], debug=True)

so when i go to 'myapp.com/test/fruits/green

parama = fruit paramb = green

:D

a.m.
  • 2,108
  • 5
  • 24
  • 29
1

Is this what you're looking for? http://code.google.com/appengine/docs/python/tools/webapp/running.html#URL_Mappings

Instead of http://test.com/browse?category=book&productid=A209 you can have http://test.com/browse/book/A209

class BrowseHandler(webapp.RequestHandler):

def get(self, category, product_id):
    # Display product with given ID in the given category.


# Map URLs like /browse/(category)/(product_id) to BrowseHandler.
application = webapp.WSGIApplication([(r'/browse/(.*)/(.*)', BrowseHandler)
                                 ],
                                 debug=True)

def main():
    run_wsgi_app(application)

if __name__ == '__main__':
    main()
Parker
  • 8,539
  • 10
  • 69
  • 98