49

How can I retrieve a request param a in Jinja2 template?

http://foo.bar?a=1
Kalle
  • 1,363
  • 1
  • 11
  • 7
Shankar Cabus
  • 9,302
  • 7
  • 33
  • 43

5 Answers5

89

I'm a bit late with this answer, but the other solutions don't really account for your use of Flask.

The fact that you're using Flask with Jinja2 makes your situation a bit different from other frameworks. Flask actually makes some global variables available to you in all Jinja2 templates without requiring you to pass them to the template explicitly.

To quote a part of the Flask documentation at http://flask.pocoo.org/docs/templating/#standard-context:

The following global variables are available within Jinja2 templates by default:

...

request The current request object (flask.request)

...

So for example to show the request parameter 'a' in the template:

{{ request.args.get('a') }}

The documentation link also lists the other global variables you can access in a similar way.

Kalle
  • 1,363
  • 1
  • 11
  • 7
  • thank you. So how to {{ request.args.get('a') }} to – Bold Ganbaatar Aug 26 '21 at 09:06
4

If you're using webapp2...

The query parameters can be fetched easily if you use webapp2.request like a dictionary.

webapp2.request.get('[parameter]', '[optionalDefaultValue]')

To apply your sample (http://foo.bar?a=1&b=2&c=true):

a = webapp2.request.get('a') # a = 1
b = webapp2.request.get('b') # b = 2
c = webapp2.request.get('c') # c = true, may need further parsing to make it bool

If you just want the un-parsed querystring just call:

qstring = webapp2.request.query_string 
# qstring = '?a=1&b=2&c=true

Once you have collected your variables just pass them into the jinja2.render_template() method the same as you would anything else.

It really doesn't get much easier than that.

Update:

I have a pretty unique way to manage parameters but I'll try to explain the simple version.

Assuming the following querystring

http://foo.bar?a=1&b=2&c=true

Here's how I'd write the GET handler:

class BaseHandler(webapp2.RequestHandler): 
  def jinja2(self):
    return jinja2.get_jinja2(app=self.app)

  def render_template(self, template, **context):
    self.response.write(self.jinja2.render_template(template, **context))

  def get(self, **params):
    context = {}    
    context['a'] = webapp2.request.get('a')
    context['b'] = webapp2.request.get('b')
    context['c'] = webapp2.request.get('c')
    self.render_template([template], **context)

So, the implementation I use is a little different. I also stack on a _defaults parameter that gets passed in through the router, and a _meta (ie title/description/url) parameter that is created by doing a uri lookup on a custom urls structure.

In my base handler, I setup jinja and wrap the instance in a method that's easier to call (ie render_template). I didn't come up with this idea, I think I got it from the webapp2 docs but I digress.

The important part is the 'context' parameter. That's where you stack in all the data you want to send to the template. Now, any value that is available in that object will now be available in the template.

For instance you could print the value for 'a' using:

{{ a }}

If you pass in an array of values as one of the parameters you can also enumerate through them and call specific properties directly using dot notation.

How your handlers are structured is completely up to you. Unlike a lot of frameworks, GAE provides a lot of flexibility in this aspect. The way I do it involves a lot of inheritance so I don't have to repeat much. It's a little difficult to explain in better detail without pasting my whole handlers.py but this is the gist of my base handler that all the rest of my handlers inherit from. The only notable difference is I define context as self.context so the child classes can access it. It seems pretty convoluted in the code but once everything is wired up, it's almost effortless to add additional pages/routes.

Evan Plaice
  • 13,944
  • 6
  • 76
  • 94
1

If you want the query parameters from url, you can use this in jinja:

request.query_string.decode()
Ahmad
  • 8,811
  • 11
  • 76
  • 141
0

In your Jinja2 template if you define it like below:::

<h2><a href="{{url_for('single_thing', id='2', pid='34')}}">{{some_value}}</a> </h2>

Your URI will be:::

http://127.0.0.1:5000/single_thing?pid=34&id=2
defau1t
  • 10,593
  • 2
  • 35
  • 47
0

You will need to pass this information to your jinja2 templates, since it is just a templating engine, and not the web framework.

The "view generation" part of your web framework that deals with requests will usually be passed some HTTP request header information or data structure. this often includes the request params. If it does, then you can just pass this to your template.

Even if the header info you get doesn't include the request params, it will always include the url. Once you have the url in your view function code, you can do something like this:

url = "http://foo.bar?a=1&b=2&c=true" # actually get this from your http request header
import urlparse
split_result = urlparse.urlsplit(url)
request_params = dict(urlparse.parse_qsl(split_result.query))
# request_params = {'a': '1', 'b': '2', 'c': 'true'}

Then you can send this request_params dictionary to your jinja template.

Preet Kukreti
  • 8,417
  • 28
  • 36
  • But many controllers use the same template. So I need to do this on all controllers, when I could do only once in the template =/ – Shankar Cabus Mar 10 '12 at 17:38
  • 1
    Depending on your web framework, it might support a "middleware" type system that wraps your views or other layers. This would mean that prior to your view function, the request parameters are extracted by your custom middleware, and after your view function, these request parameters are automatically appended to the jinja template. Even if there isnt such a mechanism you could easily do something similar with decorators. Most web apps support middleware, since it is a central concept in WSGI. – Preet Kukreti Mar 10 '12 at 18:54
  • 1
    But how retrieve this param in template (.html)? It is possible? – Shankar Cabus Sep 01 '12 at 03:21