Erik Rothoff
Erik Rothoff

Reputation: 5123

Flask url_for URLs in Javascript

What is the recommended way to create dynamic URLs in Javascript files when using flask? In the jinja2 templates and within the python views url_for is used, what is the recommended way to do this in .js files? Since they are not interpreted by the template engine.

What basically want to do is:

// in comments.js
$.post(url_for('comment.comment_reply'));

Which is not possible.

But naturally, I can execute that in a template:

<script>
    $.post(url_for('comment.comment_reply'));
</script>

Upvotes: 45

Views: 60492

Answers (9)

psychic_coder
psychic_coder

Reputation: 31

I was able to pass a dynamically created url route to a javascript function by using "tojson" with Jinja2 and Flask.

To pass the dynmaic url from the html template to js, simply add '|tojson' at the end of your jinja statment to convert it to the appropriate format.

Instead of:

<script>
 $.post(url_for('comment.comment_reply'));
</script>

Try:

<script>
 var route = {{ url_for('comment.comment_reply')|tojson }};
 yourJavaScriptFunction(route);
</script>

Then you will be able to use the route in your js functions as the correct route for whatever you need.

yourJavaScriptFunction(route){
 console.log(route);
}

Upvotes: 1

Arindam Roychowdhury
Arindam Roychowdhury

Reputation: 6511

I was trying to call a FLASK route when a button is pressed. It should collect the response and update a div. The page should not reload.

I used jquery to do this.

Here's the code:

@app.route('/<name>')
def getContent(name):
    return 'This is %s' % name

HTML:

    <div id="mySpace" class="my-3">Count</div>

    <button id="next_id" class="btn btn-primary">Press</button>

    <script>
        $('#next_id').click(function (){
            $.get('/aroy', function(data, status){
            $('#mySpace').html(data);
        });
        });
    </script>

Upvotes: -2

Edmilson Mello
Edmilson Mello

Reputation: 1

I suggest this:

<script src="{{ url_for('static', filename='js/jquery.js') }}" type="text/javascript">
</script>

Works fine for me

Upvotes: -3

Louis T
Louis T

Reputation: 671

Was searching for a solution, them come up with this solution where

  • No add-on is required

  • No hard-coding URL

The key is to realise Jinja2 has the ability to render javascript out of the box.


Setup your template folder to something like below:

/template
    /html
        /index.html
    /js
        /index.js

In your views.py

@app.route("/index_js")
def index_js():
    render_template("/js/index.js")

Now instead of serving the javascript from your static folder. You would use:

<script src="{{ url_for('index_js') }}"></script>

After all, you are generating the javascript on the fly, it is no longer a static file.


Now, inside of you javascript file, simply use the url_for as you would in any html file.

For example using Jquery to make an Ajax request

$.ajax({
  url: {{ url_for('endpoint_to_resource') }},
  method: "GET",
  success: call_back()
})

Upvotes: 8

Cole Murray
Cole Murray

Reputation: 593

In my case, I was trying to dynamically create urls

I solved my issue as follows (Note: I've swapped out Angular's syntax to {[x]}:

<ul>
    <li ng-repeat="x in projects">
        {[x.title]}
        {% set url = url_for('static',filename="img/") %}

        <img src="{{url}}{[x.img]}">
    </li>
</ul>

Upvotes: 1

Stewart Park
Stewart Park

Reputation: 416

What @dumbmatter's suggesting is pretty much considered a de facto standard way. But I thought there would be a nicer way of doing it. So I managed to develop this plugin: Flask-JSGlue.

After adding {{ JSGlue.include() }}, you can do the following in your source code:

<script>
    $.post(Flask.url_for('comment.comment_reply', {article_id: 3}));
</script>

or:

<script>
    location.href = Flask.url_for('index', {});
</script>

Upvotes: 40

Jacopofar
Jacopofar

Reputation: 3507

I use this dirty and ugly trick:

"{{url_for('mypage', name=metadata.name,scale=93,group=2)}}"
.replace('93/group',scale+'/group')

where scale is the javascript variable I want to use for an AJAX request. So, url_for generate an URL and JavaScript replace the parameter at runtime. The generated code is something like:

"/ajaxservive/mynam/scale/93/group/2".replace('93/group',scale+'/group')

which is pretty strange, but still can't find more elegant solutions.

In fact, looking at the code of the linked flask extension, it does the same thing but managing the general case.

Upvotes: 2

Yaniv Aknin
Yaniv Aknin

Reputation: 4253

@jeremy's answer is correct and probably the more common approach, but as an alternative answer, note that dantezhu wrote and published a flask extension that claims to do the exact url-route-map-to-javascript translation suggested in the comment.

Upvotes: 3

dumbmatter
dumbmatter

Reputation: 9673

The Flask documentation suggests using url_for in your HTML file to set a variable containing the root URL that you can access elsewhere. Then, you would have to manually build the view URLs on top of that, although I guess you could store them similar to the root URL.

Upvotes: 17

Related Questions