How to pass current request params to Symfony2 route - templates

I'm trying to create language/locale switch urls using Symfony2 and twig which will allow to switch language for route without resetting url:
http://example.com/en/cat/test
http://example.com/it/cat/test
http://example.com/sp/cat/test
...
and so on
Here is revelant part of my twig template:
English
My problem is that for example using category url(http://example.com/en/cat/test) gives me exception:
The "_category" route has some missing mandatory parameters ("category").
Which is all okay and understandable since for switcher urls I'm passing only _locale param.
How to pass all current url params?

You can get all request attributes from app.request and override part of them.
<a href="{{ path(app.request.attributes.get('_route'), app.request.attributes.get('_route_params')|merge({'_locale':'en'}))}}">

Related

Is there a way to apply a filter to a URL generated with the URL tag in Django?

For part of my user interface I need a URLencoded URL.
This code doesn't work, but it's intended to give an impression of what I'd like to do:
{% url 'team_event_calendar' id=team.id | urlencode %}
Basically, get a particular URL - in this case "team_event_calendar" for a particular team, and then URLencode it.
I suppose I could make a new version of the URL tag which URLencodes everything, but is there a way to do it with just Django's built-in tags?

Add url parameters to a url in django view

I have a django view that lists several urls on external sites.
When I render them I would like to add a few url parameters to each.
These urls are to an external system and thus not listed in my urls.py. Furthermore, some of the links have a hash '#' so it is not as easy as appending a few parameters to the end of the string.
Based on these requirements it seems the url template tag will not be a good fit. I was wondering if there is a custom filter out that to do this.
You don't need Django's url tag here. The url tag is to resolve to URLs that belong to your application.
However, there is the nice django-spurl library. It allows you to handle query parameters via template tags.
An example from the documentation to add query parameters:
{% spurl base="http://example.com/?foo=bar" add_query="bar=baz" %}
<!--
will result in: http://example.com?foo=bar&bar=baz
-->

Flask - how to get query string parameters into the route parameters

Im very much new to Flask, and one of the starting requirements is that i need SEO friendly urls.
I have a route, say
#app.route('/sales/')
#app.route(/sales/<address>)
def get_sales(addr):
# do some magic here
# render template of sales
and a simple GET form that submits an address.
<form action={{ url_for('get_sales') }}>
<input type='text' name='address'>
<input type=submit>
</form>
On form submission, the request goes to /sales/?address=somevalue and not to the standard route. What options do I have to have that form submit to /sales/somevalue ?
I feel like I'm missing something very basic.
You would need to use JavaScript to achieve this so your template would become:
<input type='text' id='address'>
<button onclick="sendUrl();">submit</button>
<script>
function sendUrl(){
window.location.assign("/sales/"+document.getElementById("address").value);
}
</script>
and your routes similar to before:
#app.route('/sales/')
#app.route('/sales/<address>')
def get_sales(address="Nowhere"):
# do some magic here
# render template of sales
return "The address is "+address
However, this is not the best way of doing this kind of thing. An alternative approach is to have flask serve data and use a single-page-application framework in javascript to deal with the routes from a user interface perspective.
There is a difference between the request made when the form is submitted and the response returned. Leave the query string as is, as that is the normal way to interact with a form. When you get a query, process it then redirect to the url you want to display to the user.
#app.route('/sales')
#app.route('/sales/<address>')
def sales(address=None):
if 'address' in request.args:
# process the address
return redirect(url_for('sales', address=address_url_value)
# address wasn't submitted, show form and address details
I'm not sure there's a way to access the query string like that. The route decorators only work on the base url (minus the query string)
If you want the address in your route handler then you can access it like this:
request.args.get('address', None)
and your route handler will look more like:
#pp.route('/sales')
def get_sales():
address = request.args.get('address', None)
But if I were to add my 2 cents, you may want to use POST as the method for your form posting. It makes it easier to semantically separate getting data from the Web server (GET) and sending data to the webserver (POST) :)

Can you check the internet protocol from Django's template?

Right now, if I want to check whether the current page is accessed through http:// or https://, I will use the following Javascript in my templates and write html from document.write:
<script type="text/javascript">
var protocol = document.location.protocol;
if (protocol == "http:")
document.write("regular");
else
document.write("secured");
</script>
Is there another way to achieve the above in Django's template without using Javascript?
if you use a RequestContext, you can do the following:
<p>You used: {% if request.is_secure %}HTTPS{% else %}HTTP{% endif %}
See the relevant part of the Django documentation.
Since Django 1.10, you can use:
request.scheme
in a view, or in a template:
{{ request.scheme }}
From the docs
A string representing the scheme of the request (http or https usually).
You need to enable the appropriate request context processor in your setting.py file:
TEMPLATE_CONTEXT_PROCESSORS = ('django.core.context_processors.request',)
The template will now have a variable named request that contains the current HttpRequest. You can use it to find the protocol:
{{ request.is_secure }}
Try using RequestContext and request.is_secure in your template.
One caveat, the process of detecting HTTPS can differ from one server setup to the next so you may have to do a little work to get request.is_secure working. You can get it working either by ensuring that your front end / reverse proxy sets 'HTTP_X_FORWARDED_HOST' or by writing a middleware class that is custom to your setup.
Use the deprecated SetRemoteAddrFromForwardedFor code as a starting point, if you go the custom middleware route.

View referenced by two urls and url tag

I am using url tag in my template for a view, that is used by two different urls. I am getting the wrong url in one place. Is there any way to force django to retrieve different url? Why it doesn't notify my, that such conflict occured and it doesn't know what to do (since python zen says, that is should refuse temptation to guess).
Code in template:
{% url djangoldap.views.FilterEntriesResponse Entry=entry.path as filter_url %}
Code in urls:
(r'^filter_entries/(?P<Entry>.*)/$',
'djangoldap.views.FilterEntriesResponse',
{'filter_template': 'filter_entries.html',
'results_template': 'filter_results.html'}),
(r'^choose_entries/(?P<Entry>.*)/$',
'djangoldap.views.FilterEntriesResponse',
{'filter_template': 'search_entries.html',
'results_template': 'search_results.html'}),
As you can see, those two urls use the same view, but with different templates. How I can force django to retrieve former url, rather than latter?
Name your URLs by adding another item to the tuple:
(r'^choose_entries/(?P<Entry>.*)/$',
'djangoldap.views.FilterEntriesResponse',
{'filter_template': 'search_entries.html',
'results_template': 'search_results.html'},
'sensibleprefix-choose_entries') # <-- this is the name
Then you can use the name in the URL tag.