46

In my Flask app, I have a view which displays a post

@post_blueprint.route('/post/<int:year>/<int:month>/<title>') def get_post(year,month,title): # My code 

To display the last 10 entries, I have following view:

@post_blueprint.route('/posts/') def get_all_posts(): # My code return render_template('p.html',posts=posts) 

Now when I display the last 10 posts, I want to convert the title of a post into a hyperlink. Currently I have to do the following in my jinja template to achieve this:

<a href="/post/{{year}}/{{month}}/{{title}}">{{title}}</a> 

Is there any way to avoid hard coding the url?

Like url_for function which is used to create Flask urls like this:

url_for('view_name',**arguments) 

I have tried searching for one but I,m not able to find it.

1
  • So you'd like to have url_for use kwargs? The only way to do that would be to have posts as a list of dicts. I don't believe there's a way for that to be done without changing your logic in the view first. Commented Jun 20, 2012 at 18:07

1 Answer 1

89

I feel like you're asking two questions here but I'll take a shot...

For the posting url you'd do this:

<a href="{{ url_for('post_blueprint.get_post', year=year, month=month, title=title)}}"> {{ title }} </a> 

To handle static files I'd highly suggest using an asset manager like Flask-Assets, but to do it with vanilla flask you do:

{{ url_for('static', filename='[filenameofstaticfile]') }} 

If you'd like more information I highly suggest you read. http://flask.pocoo.org/docs/quickstart/#static-files and http://flask.pocoo.org/docs/quickstart/#url-building

Edit for using kwargs:

Just thought I'd be more thorough...

If you'd like to use url_for like this:

{{ url_for('post_blueprint.get_post', **post) }} 

You have to change your view to something like this:

@post_blueprint.route('/posts/') def get_all_posts(): models = database_call_to_fetch_posts() # This is assuming you use some kind of data-model posts = [] for model in models: posts.append(dict(year=model.year, month=model.month, title=model.title)) return render_template('p.html', posts=posts) def database_call_to_fetch_posts(): posts = [] # fetch posts here as a list of objects ... return posts 

Then your template code can look like this:

{% for post in posts %} <a href="{{ url_for('post_blueprint.get_post', **post) }}"> {{ post['title'] }} </a> {% endfor %} 

At this point I would actually create a method on the model so you don't have to turn it into a dict, but going that far is up to you :-).

Sign up to request clarification or add additional context in comments.

2 Comments

What is the models type and why we need to turn it into a dict? Can't we pass it to our view and just iterate there?
@davidism: "models" here are the data models you might define to store your Post objects into database. In this example, "models" fetch data with a custom schema defined for the database. Consider each model as an Object containing data for a Post. He put all the object attributes into a dict for each Post. Then you can have (key,value) pairs of Post attribute and its corresponding value). This way, it would be much easier to access passed attributes in templates. You can also send it as a list and iterate there (not recommended!), but you should memorize the order all the time.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.