Package: django-spurl
.=.,
         ;c =\
       __|  _/
     .'-'-._/-'-._
    /..   ____    \
   /  {% spurl %}  \
  (  / \--\_>/-/'._ )
   \-;_/\__;__/ _/ _/
    '._}|==o==\{_\/
     /  /-._.--\  \_
    // /   /|   \ \ \
   / | |   | \;  |  \ \
  / /  | :/   \: \   \_\
 /  |  /.'|   /: |    \ \
 |  |  |--| . |--|     \_\
 / _/   \ | : | /___--._) \
|_(---'-| >-'-| |       '-'
       /_/     \_\Spurlis a Django template library for manipulating URLs. It’s built
on top of Zachary Voase’s excellenturlobject.Authored byJamie Matthews, and some greatcontributors.InstallationEither checkoutspurlfrom GitHub, or install using pip:pipinstalldjango-spurlAddspurlto yourINSTALLED_APPS:INSTALLED_APPS=(...'spurl',)Finally, whenever you want to use Spurl in a template, you need to load
its template library:{%loadspurl%}UsageSpurl isnota replacement for Django’s built-in{% url %}template tag. It is a general-purpose toolkit for manipulating URL
components in templates. You can use it alongside{% url %}if you
like (see below).Spurl provides a single template tag, called (surprisingly enough),spurl. You call it with a set ofkey=valuekeyword arguments,
which are described fully below.To show some of the features of Spurl, we’ll go over a couple of simple
example use cases.Adding query parameters to URLsSay you have a list of external URLs in your database. When you create
links to these URLs in a template, you need to add areferrer=mysite.comquery parameter to each. The simple way to do
this might be:{%forurl,titleinlist_of_links%}<ahref="{{url}}?referrer=mysite.com">{{title}}</a>{%endfor%}The problem here is that you don’t know in advance if the URLs stored in
your databasealreadyhave query parameters. If they do, you’ll
generate malformed links likehttp://www.example.com?foo=bar?referrer=mysite.com.Spurl can fix this. Because it knows about the components of a URL, it
can add parameters onto an existing query, if there is one.{%forurl,titleinlist_of_links%}<ahref="{%spurlbase=urladd_query="referrer=mysite.com"%}">{{title}}</a>{%endfor%}Note thatwhen you pass a literal string to Spurl, you have to wrap it
in double quotes. If you don’t, Spurl will assume it’s a variable name
and try to look it up in the template’s context.SSL-sensitive external URLs.Suppose your site needs to display a gallery of images, the URLs of
which have come from some third-party web API. Additionally, imagine
your site needs to run both in secure and non-secure mode - the same
content is available at bothhttpsorhttpURLs (depending on
whether a visitor is logged in, say). Some browsers will complain loudly
(displaying “Mixed content warnings” to the user) if the page being
displayed ishttpsbut some of the assets arehttp. Spurl can
fix this.{%forimage_urlinlist_of_image_urls%}<imgsrc="{%spurlbase=image_urlsecure=request.is_secure%}"/>{%endfor%}This will take the image URL you supply and replace the scheme component
(thehttporhttpsbit) with the correct version, depending on
the return value ofrequest.is_secure(). Note that the above assumes
you’re using aRequestContextso thatrequestis available in
your template.Using alongside{% url %}Notice that Spurl’s functionality doesn’t overlap with Django’s built-in{% url %}tag. Spurl doesn’t know about your urlconf, and doesn’t do
any URL reversing. In fact, Spurl is mostly useful for manipulatingexternalURLs, rather than URLs on your own site. However, you can
easily use Spurl with{% url %}if you need to. You just have to use
theaskeyword to put your reversed URL in a template variable, and
then pass this to Spurl. As it’s a relative path (rather than a full
URL) you should pass it using thepathargument. For example, say
you want to append some query parameters to a URL on your site:{%urlyour_url_nameasmy_url%}<ahref="{%spurlpath=my_urlquery="foo=bar&bar=baz"%}">Click here!</a>There is another way to use Spurl with{% url %}, seeEmbedding
template tagsbelow.Available argumentsBelow is a full list of arguments that Spurl understands.baseIf you pass abaseargument to Spurl, it will parse its contents and
use this as the base URL upon which all other arguments will operate. If
youdon’tpass abaseargument, Spurl will generate a URL from
scratch based on the components that you pass in separately.schemeSet the scheme component of the URL. Example:{%spurlbase="http://example.com"scheme="ftp"%}This will returnftp://example.comSee also:scheme_from, below.hostSet the host component of the URL. Example:{%spurlbase="http://example.com/some/path/"host="google.com"%}This will returnhttp://google.com/some/path/See also:host_from, below.authHandle HTTP Basic authentication, username and password can be passed in
URL. Example:{%spurlbase="https://example.com"auth="user:pass"%}This will returnhttps://user:pass@example.compathSet the path component of the URL. Example:{%spurlbase="http://example.com/some/path/"path="/different/"%}This will returnhttp://example.com/different/See also:path_from, below.add_pathAppend a path component to the existing path. You can add multipleadd_pathcalls, and the results of each will be combined. Example:{%spurlbase=STATIC_URLadd_path="javascript"add_path="lib"add_path="jquery.js"%}This will returnhttp://cdn.example.com/javascript/lib/jquery.js(assumingSTATIC_URLis set tohttp://cdn.example.com)See also:add_path_from, below.fragmentSet the fragment component of the URL. Example:{%spurlbase="http://example.com"fragment="myfragment"%}This will returnhttp://example.com/#myfragmentSee also:fragment_from, below.portSet the port component of the URL. Example:{%spurlbase="http://example.com/some/path/"port="8080"%}This will returnhttp://example.com:8080/some/path/See also:port_from, below.querySet the query component of the URL. Example:{%spurlbase="http://example.com/"query="foo=bar&bar=baz"%}This will returnhttp://example.com/?foo=bar&bar=bazThequeryargument can also be passed a dictionary from your
template’s context.# views.pydefmy_view(request):my_query_params={'foo':'bar','bar':'baz'}returnrender(request,'path/to/template.html',{'my_query_params':my_query_params})<!-- template.html -->{%spurlbase="http://example.com/"query=my_query_params%}This will returnhttp://example.com/?foo=bar&bar=bazFinally, you can pass individual template variables to the query. To do
this, Spurl uses Django’s template system. For example:{%spurlbase="http://example.com/"query="foo={{ variable_name }}"%}See also:query_from, below.add_queryAppend a set of parameters to an existing query. If your base URL might
already have a query component, this will merge the existing parameters
with your new ones. Example:{%spurlbase="http://example.com/?foo=bar"add_query="bar=baz"%}This will returnhttp://example.com?foo=bar&bar=bazYou can add multipleadd_querycalls, and the results of each will
be combined:{%spurlbase="http://example.com/"add_query="foo=bar"add_query="bar=baz"%}This will returnhttp://example.com?foo=bar&bar=bazLike thequeryargument above, the values passed toadd_querycan also be dictionaries, and they can contain Django template
variables.See also:add_query_from, below.set_queryAppends a set of parameters to an existing query, overwriting existing
parameters with the same name. Otherwise uses the exact same syntax asadd_query.See also:set_query_from, below.toggle_queryToggle the value of one or more query parameters between two possible
values. Useful when reordering list views. Example:{%spurlbase=request.get_full_pathtoggle_query="sort=ascending,descending"%}If the value ofrequest.get_full_path()doesn’t have asortparameter, one will be added with a value ofascending(the first
item in the list is the default). If it already has asortparameter, and it is currently set toascending, it will be set todescending. If it’s already set todescending, it will be set toascending.You can also specify the options as a dictionary, mapping the parameter
name to a two-tuple containing the values to toggle. Example:# views.pySORT_PARAM='sort'ASCENDING='ascending'DESCENDING='descending'defmy_view(request):ifrequest.GET.get(SORT_PARAM,ASCENDING)==DESCENDING:object_list=MyModel.objects.order_by('-somefield')else:object_list=MyModel.objects.order_by('somefield')returnrender(request,'path/to/template.html',{'object_list':object_list,'sort_params':{SORT_PARAM:(ASCENDING,DESCENDING)},})<!-- template.html --><ahref="{%spurlbase=request.get_full_pathtoggle_query=sort_params%}">Reverse order</a>remove_query_paramRemove a query parameter from an existing query:{%spurlbase="http://example.com/?foo=bar&bar=baz"remove_query_param="foo"%}This will returnhttp://example.com?bar=bazAgain, you can add multipleremove_query_paramcalls, and the
results will be combined:{%spurlbase="http://example.com/?foo=bar&bar=baz"remove_query_param="foo"remove_query_param="bar"%}This will returnhttp://example.com/You can also remove parameters with specific values:{%spurlbase="http://example.com/?foo=bar&bar=baz&foo=baz"remove_query_param="foo"remove_query_param="foo=baz"%}This will returnhttp://example.com/?bar=bazFinally, you can pass individual template variables to theremove_query_paramcalls. To do this, Spurl uses Django’s template
system. For example:{%spurlbase="http://example.com/?foo=bar&bar=baz"remove_query_param="{{ variable_name }}"%}secureControl whether the generated URL starts withhttporhttps. The
value of this argument can be a boolean (TrueorFalse), if
you’re using a context variable. If you’re using a literal argument
here, it must be a quoted string. The strings"True"or"on"(case-insensitive) will be converted toTrue, any other string will
be converted toFalse. Example:{%spurlbase="http://example.com/"secure="True"%}This will returnhttps://example.com/autoescapeBy default, Spurl will escape its output in the same way as Django’s
template system. For example, an&character in a URL will be
rendered as&amp;. You can override this behaviour by passing anautoescapeargument, which must be either a boolean (if passed from
a template variable) or a string. The strings"True"or"on"(case-insensitive) will be converted toTrue, any other string will
be converted toFalse.Added bonus:_fromparametersAs well as those listed above, Spurl provides a family of parameters forcombiningURLs. Given a base URL to start with, you can copy a
component from another URL. These arguments expect to be passed a full
URL (or anything that can be understood byURLObject.parse). This
URL will be parsed, and then the component in question will be extracted
and combined with the base URL.Below is a full list of the available_frommethods. They have
identical semantics to their counterparts above (except they expect a
full URL, not just a URL component).query_fromadd_query_fromset_query_fromscheme_fromhost_frompath_fromadd_path_fromfragment_fromport_fromExample:{%spurlbase="http://example.com/foo/bar/?foo=bar path_from="http://another.com/something/?bar=foo"%}This will returnhttp://example.com/something/?foo=barBuilding a URL without displaying itLike Django’s{% url %}tag, Spurl allows you to insert the
generated URL into the template’s context for later use. Example:{%spurlbase="http://example.com"secure="True"assecure_url%}<p>The secure version of the url is{{secure_url}}</p>Embedding template tagsAs mentioned above, Spurl uses Django’s template system to individually
parse any arguments which can be passed strings. This allows the use of
syntax such as:{%spurlbase="http://example.com"add_query="foo={{ bar }}"%}This works fine for variable and filters, but what if we want to use
other template tagsinsideour Spurl tag? We can’t nest{%and%}tokens inside each other, because Django’s template parser would
get very confused. Instead, we have to escape the inner set of tag
markers with backslashes:{%spurlbase="http://example.com"add_query="next={\% url home %\}"%}Note that any tags or filters loaded in your template are automatically
available in the nested templates used to render each variable. This
means we can do:{%loadurlfromfuture%}{%spurlbase="{\% url 'home' %\}"%}Be careful with your quotation marks! If you use double-quotes to
surround the nested template, you have to use single quotes inside it.Warning!This functionality only exists to serve the most complex of
use cases, and is extremely magical (and probably a bad idea). You may
prefer to use:{%url"home"asmy_url%}{%spurlbase=my_url%}DevelopmentTo contribute, fork the repository, make your changes, add some tests,
commit, push, and open a pull request.How to run the testsSpurl is tested withnose. Clone the
repository, then runpip install-rrequirements.txtto install nose
and Django into your virtualenv. Then, simply typenoseteststo find
and run all the tests.(Un)licenseThis is free and unencumbered software released into the public domain.Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any means.In jurisdictions that recognize copyright laws, the author or authors of
this software dedicate any and all copyright interest in the software to
the public domain. We make this dedication for the benefit of the public
at large and to the detriment of our heirs and successors. We intend
this dedication to be an overt act of relinquishment in perpetuity of
all present and future rights to this software under copyright law.THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.For more information, please refer tohttp://unlicense.org/Artwork creditSuperman ASCII art comes fromhttp://ascii.co.uk/art/supermanChanges0.6.8 (2021-11-15)Fixtoggle_querysupport when one word is a fragment of the other.0.6.7 (2020-05-22)Fixed MANIFEST.in0.6.6 (2019-03-29)Added support for an except clause to remove all but specifed query vars.0.6.5 (2018-05-09)Added support for Django 2.x and dropped support for older and
non-LTS version of Django.0.6.4 (2015-12-26)Getting ready for Django 1.10 release.Dropped support for Django 1.3 and older.0.6.3 (2015-12-17)Django 1.9 compatible (Albert Koch)0.6.2 (2015-09-17)Add support for template variables toremove_query_param.Handle auth parameters to be able to add username:password to URLs.0.6.1 (2015-07-14)Python 3 compatible!0.6.0 (2012-02-23)Upgrade URLObject dependency to 2.00.5.0 (2011-12-14)Fix typos in changelog.Add family of arguments (_from) for combining URLs.Addtoggle_queryargument.0.4.0 (2011-12-07)Upgrade URLObject dependency to 0.6.0Addremove_query_paramargument.Add support for template tags embedded within argument values.Extensive refactoring.0.3.0 (2011-08-18)Addset_queryargument.0.2.0 (2011-08-08)Addasargument to insert generated URL into template context.0.1.0 (2011-07-29)Initial release.