{ "info": { "author": "Tomek Paczkowski & Aleksandra Sendecka", "author_email": "tomek@hauru.eu", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Environment :: Web Environment", "Framework :: Django", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 3" ], "description": "Django Happy Urls\n=================\n\nComments/feedback is very welcome, use issues or twitter:\nhttps://twitter.com/oinopion\n\n.. image:: https://secure.travis-ci.org/oinopion/hurl.png\n\nDjango has nice routing, but it's too low level. Regexps are powerful,\nbut have cryptic syntax. This library strives to make writing DRY\nurls a breeze.\n\nConsider a standard urls.py::\n\n urlpatterns = patterns('blog.entries.views',\n url(r'^$', 'recent_entries', name='entries_recent_entries'),\n url(r'^new/$', 'new_entry', name='entries_new_entry'),\n url(r'^(?P[\\w-]+)/$', 'show_entry', name='entries_show_entry'),\n url(r'^(?P[\\w-]+)/edit/$', 'edit_entry', name='entries_edit_entry'),\n url(r'^(?P[\\w-]+)/delete/$', 'delete_entry', name='entries_delete_entry'),\n url(r'^(?P[\\w-]+)/comments/$', 'comments_list', name='entries_comments_list'),\n url(r'^(?P[\\w-]+)/comments/(\\d+)/$', 'comment_details', name='entries_comment_detail'),\n )\n\nIt has many issues:\n\n- you need to remember about the '^' and the '$'\n- you repeat the entry_slug url\n- you need to remember arcane named group syntax\n- you repeat the [\\\\w-]+ group\n- you associate name with urls conf\n\nBetter way of writing urls would be::\n\n urlpatterns = hurl.patterns('blog.entries.views', [\n ('', 'recent_entries'),\n ('new', 'new_entry'),\n ('', [\n ('', 'show_entry'),\n ('edit', 'edit_entry'),\n ('delete', 'delete_entry'),\n ('comments', 'comments_list'),\n ('comments/<:int>', 'comment_detail'),\n ]),\n ])\n\nIt conveys url structure more clearly, is much more readable and\navoids repetition. If your views don't rely on order, you can also use\ndictionary like this::\n\n urlpatterns = hurl.patterns('blog.entries.views', {\n 'show': 'show_entry',\n 'edit': 'edit_entry',\n 'delete': 'delete_entry',\n })\n\n\nHow to use it\n-------------\n\npatterns (prefix, url_conf)\n\n * prefix is same as in django.conf.url.patterns\n * url_conf is either a dictionary or a list of 2-tuples\n The key (in dict) or first element (tuple) is a url fragment,\n value/second element can be one of: another url_conf, a string, an instance\n of ViewSpec::\n\n {\n 'show': 'blog.views.show_entry',\n }\n\n is equivalent to::\n\n [\n ('show', 'blog.views.show_entry'),\n ]\n\n URL conf creates a tree of url fragments and generates a list\n by joining each fragment with the \"/\"::\n\n {\n 'entries': {\n 'edit': 'edit_entry',\n 'delete': 'delete_entry',\n }\n }\n\n This will generate these urls::\n\n (r'^entries/edit/$', 'edit_entry', name='edit_entry')\n (r'^entries/delete/$', 'delete_entry', name='edit_entry')\n\n\n Url fragment may include multiple parameters in format::\n\n ''\n\n parameter_name can be any python identifier\n parameter_type must be one of default or defined matchers\n\n If you have parameter_type same as parameter_name, you can skip\n duplication and use shorter form::\n\n '' -> ''\n\n If you want to use default matcher also use shortcut::\n\n '' -> ''\n\n If you don't want to define parameter name, leave it empty::\n\n '<:int>' # will generate r'(\\d+)'\n\n\n\nDefault Matchers\n----------------\n\n :slug:\n\n r'[\\w-]+'\n This is the default matcher.\n\n :int:\n\n r'\\d+'\n\n :str:\n\n r'[^/]+'\n\nCustom Matchers\n---------------\n\nYou can define your own matchers. Just instantiate Hurl and set::\n\n import hurl\n h = hurl.Hurl()\n h.matchers['year'] = r'\\d{4}'\n\n urlpatterns = h.patterns('', {'': 'year_archive'})\n\n.. note::\n\n When defining custom matchers use the 'patterns' method of your instance,\n rather than function provided by module.\n\nNames generation\n----------------\n\nHurl will automatically generate view names for you. When provided with\nview as string ('blog.views.show_entry') it will take last part after the dot.\nWhen provided with function it will take the func_name of it::\n\n def some_view(req):\n pass\n\n urlpatterns = hurl.patterns('', {\n 'show': 'blog.views.show_entry', # generates 'show_entry' name\n 'some': some_view, # generates 'some_view' name\n })\n\nYou can also want to change the name use the 'v' function::\n\n import hurl\n urlpatterns = hurl.patterns('', {\n 'show': hurl.v('show_view', name='show'),\n })\n\nIncludes\n--------\n\nIf you want to include some other urlpatterns, use the `include` method::\n\n import hurl\n urlpatterns = hurl.patterns('', {\n 'shop': hurl.include('shop.urls'),\n 'blog': hurl.include('blog.urls'),\n })\n\n\nMixing with pure Django urls\n----------------------------\n\nHurl doesn't do anything special, it just generates plain old Django urls.\nYou can easily mix two APIs::\n\n from django.conf.urls import url, include, patterns\n import hurl\n\n urlpatterns = patterns('', # plain Django\n url(r'^hello/$\n )\n\n\nMore examples\n-------------\n\nDjango tutorial::\n\n # original:\n urlpatterns = patterns('',\n (r'^articles/2003/$', 'news.views.special_case_2003', {}, 'news_special_case_2003'),\n (r'^articles/(?P\\d{4})/$', 'news.views.year_archive', {}, 'news_year_archive'),\n (r'^articles/(?P\\d{4})/(?P\\d{2})/$', 'news.views.month_archive', {}, 'news_month_archive'),\n (r'^articles/(?P\\d{4})/(?P\\d{2})/(?P\\d{2})/$', 'news.views.article_detail', {}, 'news_article_detail'),\n )\n\n # hurled:\n hurl = Hurl(name_prefix='news')\n hurl.matchers['year'] = r'\\d{4}'\n hurl.matchers['month'] = r'\\d{2}'\n hurl.matchers['day'] = r'\\d{2}'\n\n urlpatterns = hurl.patterns('news.views', {\n 'articles': {\n '2003': 'special_case_2003',\n '': 'year_archive',\n '/': 'month_archive',\n '//': 'article_detail',\n }\n })", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/oinopion/hurl", "keywords": null, "license": "New BSD License", "maintainer": null, "maintainer_email": null, "name": "hurl", "package_url": "https://pypi.org/project/hurl/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/hurl/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://github.com/oinopion/hurl" }, "release_url": "https://pypi.org/project/hurl/2.1/", "requires_dist": null, "requires_python": null, "summary": "UNKNOWN", "version": "2.1" }, "last_serial": 638487, "releases": { "1.0": [ { "comment_text": "", "digests": { "md5": "b4b0f2b0359cbf10243cb56f8a0dc1c3", "sha256": "43f1747a73ea6ed3d4e577213cd7da865ad47a9b054a6e39d01990cc8de671a8" }, "downloads": -1, "filename": "hurl-1.0.tar.gz", "has_sig": false, "md5_digest": "b4b0f2b0359cbf10243cb56f8a0dc1c3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 1510, "upload_time": "2012-06-04T08:51:44", "url": "https://files.pythonhosted.org/packages/28/de/5757f060dc2039b7340e00959dcf0d89a9c899017cba366819982b147840/hurl-1.0.tar.gz" } ], "2.0": [ { "comment_text": "", "digests": { "md5": "00d0bc4c904be9765e55c193c496222d", "sha256": "649a5692ae54fcdb5ec38097eed91dd38dc7f31bdd97f9fc46d60ced5c7a9903" }, "downloads": -1, "filename": "hurl-2.0.tar.gz", "has_sig": false, "md5_digest": "00d0bc4c904be9765e55c193c496222d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5625, "upload_time": "2012-10-08T14:10:33", "url": "https://files.pythonhosted.org/packages/ee/ad/d926c49c14162eb6fa80a6d0e3452b07cc463b115092bdcd608effe705a4/hurl-2.0.tar.gz" } ], "2.1": [ { "comment_text": "", "digests": { "md5": "0106a14a9e2700d10be00fd83bf21894", "sha256": "b57adb4adbb1803316af0db7154c0d5ea2957ada32bd6699ba418076e2e6c32d" }, "downloads": -1, "filename": "hurl-2.1.tar.gz", "has_sig": false, "md5_digest": "0106a14a9e2700d10be00fd83bf21894", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5827, "upload_time": "2013-04-06T18:01:28", "url": "https://files.pythonhosted.org/packages/71/04/bbb728edbe3bee5252d59577ffe0a39a4183835d9ff82991685bd946aa63/hurl-2.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "0106a14a9e2700d10be00fd83bf21894", "sha256": "b57adb4adbb1803316af0db7154c0d5ea2957ada32bd6699ba418076e2e6c32d" }, "downloads": -1, "filename": "hurl-2.1.tar.gz", "has_sig": false, "md5_digest": "0106a14a9e2700d10be00fd83bf21894", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5827, "upload_time": "2013-04-06T18:01:28", "url": "https://files.pythonhosted.org/packages/71/04/bbb728edbe3bee5252d59577ffe0a39a4183835d9ff82991685bd946aa63/hurl-2.1.tar.gz" } ] }