Yaniv K.
Yaniv K.

Reputation: 286

Flask - Redirect and passing arguments to the function

I'm implementing languages menu into my application. The main URL returns the default english page and from there you can select other languages through a menu.

This is the code:

@app.route('/')
def home_page(language='en'):
    return render_template(f"homepage - {language}.html")


@app.route('/lang=<language>')
def home_page_language(language):
    return render_template(f"homepage - {language}.html")

After you select a language, the URL is foo.foo/lang=foo, So I was wondering if there is a way to redirect to the home_page function and in the same time pass a language argument so that the URL stays clean (foo.foo)

Upvotes: 1

Views: 4739

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1121266

If all you want to do is serve the same template with the new language setting, then it helps to know that home_page() view is just a function. You can just call it:

@app.route('/lang=<language>')
def home_page_language(language):
    return home_page(language)

Better still, you can register views under multiple routes, you don't actually need a second function here; just move the /lang=<language> registration to the home_page() function:

@app.route('/')
@app.route('/lang=<language>')
def home_page(language='en'):
    return render_template(f"homepage - {language}.html")

Now / will use 'en', and /lang=foobar will call that same function with language='foobar'.

If you were hoping to actually redirect the browser back to the / URL (using a 30x Moved response), but at the same time keep the language setting, then you lose the information you stored in the URL path and have to record the language preference somewhere else. Most multilingual sites commonly store your language preference in a dedicated cookie, but you could also use the Flask session object (which also is cookie based in the default setup).

To redirect to a different URL, use the flask.redirect() function, then attach your cookie to the response object that that produces (using Response.set_cookie().

Your homepage will need to look for the language setting in the same cookie, it will not be part of the URL; I used a dedicated cookie here to store this information:

from flask import redirect, request, url_for

@app.route('/')
def home_page():
    language = request.cookies.get('language', 'en')
    return render_template(f"homepage - {language}.html")

@app.route('/lang=<language>')
def home_page_language(language):
    redirected = redirect(url_for('home_page'))
    redirected.set_cookie('language', language)
    return redirected

If you were to store this information in the session object, you don't have to manually update the redirect response, the Flask framework handles that transparently for you:

from flask import session, redirect, url_for

@app.route('/')
def home_page():
    language = session.get('language', 'en')
    return render_template(f"homepage - {language}.html")

@app.route('/lang=<language>')
def home_page_language(language):
    session['language'] = language
    return redirect(url_for('home_page'))

Upvotes: 1

Related Questions