I need to pass variable through jinja2 to base html template. If requesting python function test happens by URl - then everything is working okay. But I do need to request pyton function send_user_login_status each time when URL is changed. In this case it does not work. How can I achieve python function send_user_login_status executes every time when user changes URL and passing variable through jinja2 to .html file.
I am using flask.
base.html
<li class="{{ login_status_class }}"> {{ login_status }}</li>
test.html
{% extends "base.html" %}
Python function is working by URL correctly
#app.route('/test')
def test_api():
login_status_class = 'login'
login_status = u'Enter'
return render_template("base.html",
login_status=login_status,
login_status_class=login_status_class)
Python function has to work each time when URL changes
def send_user_login_status():
login_status_class = 'login'
login_status = u'Enter'
return render_template("base.html",
login_status=login_status,
login_status_class=login_status_class)
EDIT 1
For example, I'm trying to call a function send_user_login_status when user goes to the home page. But nothing happens.
#app.route('/')
def home():
send_user_login_status()
return render_template("index.html")
Related
I need to apply a if statement in template file based on response code with respect to a url. As I'm not aware of any direct method, I'm planning to make a custom template tag like:
from django import template
register = template.Library()
#register.filter(name='code')
def code(url):
a = http.response(url)
return a
I will then call this within the template as:
{% if model.fileurl|code==200 %}
<div>..............</div>
Also, is there any way to do it directly within the template as I'm trying to fill in the shoes of our django developer.
You can make a template tag that returns the status code:
# app/templatetags/code.py
from django import template
from requests import get as reqget
register = template.Library()
#register.filter(name='code')
def code(url):
reqget(url).status_code
The app/templatetags/ directory need to contain an __init__.py file as well (if this is not the case yet, you can add an empty one).
and then in the template:
{% load code %}
{% if model.fileurl|code == 200 %}
<div>..............</div>
{% endif %}
I doing a flask app and when i try to put a link to redirect a user to his profile page by calling
BuildError: Could not build url for endpoint 'profile'. Did you forget
to specify values ['business_name']?
when i try to login a user.My app works fine the previous days with this same code i do not what has happen and i have tried all possible means to get this right but no way
#app.route('/profile/<business_name>')
#login_required
def profile(business_name):
user = User.query.filter_by(business_name=business_name).first()
if user == None:
flash('This Profile does not exist {}'.format(business_name))
return redirect(url_for('login'))
return render_template('profile.html',user=user)
(main.html)
<ul class="nav navbar-nav">
<li>Home</li>
{% if g.user.is_authenticated %}
<li>Your Profile</li>
<li>Logout</li>
Problem is you are not defining the route view function to take in the following form:
/profile/business_name
Hence you should send business_name in URL but you are sending arguments to the function. You should do the following:
<a href="/profile/{{business_name=g.user.business_name }}">
I'm writing a small application in Flask.
run.py
#!flask/bin/python
from app import app
app.run(debug=True, port=9001)
init.py
from flask import Flask
app = Flask(__name__)
from app import views
index.html
{% extends "base.html" %}
{% block content %}
<select id = "foo">
{% for item in Citydata %}
<option value = {{ item.link }}> {{ item.name }} </option>
{% endfor %}
</select>
Click here
{% endblock %}
new.html
{% extends "base.html" %}
{% block content %}
<p>gafgafgadfgaerwgtdfzgaergdfzgaergaergaergt</p>
{% endblock %}
and lastly views.py
from flask import render_template
from app import app
from bs4 import BeautifulSoup
import urllib2
import traceback
class City_Link(object):
name = ""
link = ""
# The class "constructor" - It's actually an initializer
def __init__(self, name, link):
self.name = name
self.link = link
#app.route('/')
#app.route('/index')
def index():
URL = 'http://www.amis.pk/DistrictCities.aspx'
City_Data = scrape(URL)
return render_template("index.html",
title='Home',
Citydata=City_Data)
#app.route('/new/<data>', methods=['GET', 'POST'])
def new(data):
return render_template("new.html",
title='Home',
link = data)
def scrape(url):
data = []
try:
page = urllib2.urlopen(url)
soup = BeautifulSoup(page.read(), "lxml")
table = soup.body.find(id='TABLE1')
for row in table.findAll("tr"):
heads = row.findAll("a")
for head in heads:
data.append((City_Link(head.text.strip(), head.attrs['href'])))
except:
print(traceback.format_exc())
return data
When i click on the "Click me" href in index.html It gives me a 404 not found on the template new.html. I dont understand why because I followed a basic tutorial. I tried changing ports and it worked. But then I tried to update the code and it broke the link again.
So the reason this happens is because flask registers /new and /new/ to be two different routes.
It also looks like you're not actually passing in any data to the data variable anyway. You can temporarily fix this issue by changing your link to point to
/new/something
But that doesn't totally address the problem. I recommend adjusting your template code to make use of flasks excellent url_for function. You can find the extended documentation for it here: http://flask.pocoo.org/docs/0.10/api/#flask.url_for
When we adjust your code, it should look like:
Click here
And that data variable looks like it's not even used! Let's just strip it out totally!
#app.route('/new', methods=['GET', 'POST'])
def new():
return render_template("new.html",
title='Home')
This has altered your code, and I may not have enough information about your use case. If this modifies it beyond being usable for your application, let me know and I'll adjust my answer accordingly.
How can I update the global variable in flask passed by context processor?
I tried the following in index.html, it works for index.html, but it fails for other html files.
//(1)inside index.html
{% set user = [3,4] %}
{{user}}
//(2)inside init.py
val = [1,2]
#app.context_processor
def inject_user():
return dict(user=val)
//(3)inside layout.html
{{ user }}
So I refresh the webpage, I expect to see the layout.html will print [3,4], however, it still print [1,2].
Any idea about how to do this?
Thanks.
My layout template contains a header and I'd like to add a CSS class to the currently selected menu option.
class="active"
I thought I found the solution here but I'm still having issues. When I paste the following code into my template I get a server error.
{% rule = request.url_rule %}
Why didn't this work? How can I set a variable to control the menu in the templates?
{% rule = request.url_rule %} is not valid syntax in Jinja. If you want to set a context variable from a template, use set:
{% set rule = request.rule %}
request is already passed to each template context automatically, you don't need to pass it in render_template.
My best guess would be that the request object isn't getting passed to the template. If it isn't being passed you wouldn't be able to access it when rendering the template. You could pass it explicitly, which would look something like this:
from flask import request
from flask import render_template
#app.route('/hello/')
def hello():
return render_template('hello.html', request=request)
Someone commented that swankswashbucklers answer wouldn't fix my problem so I'm posting my solution which was inspired by his suggestion.
I simply manually set a variable called title when creating the view.
def home():
return render_template(
'index.html',
title='Home',
)
Within the template I referenced the variable to decide which menu item to highlight.
{% if title == "Home" %}
<li class="active">
{% else %}
<li>
{% endif %}
It turned out in my situation I didn't need to access the current url.