Reputation: 17617
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?
Upvotes: 3
Views: 1334
Reputation: 8851
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()
Upvotes: 1
Reputation: 2208
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
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
Upvotes: 1