Get information from python file in html [web app using flask] - python

So I am making a web app in Flask. In the layout.html file, there is a navbar on the top of the screen. It has 2 elements: Create Family and Join Family. I only want these to appear when a user a not created or joined a family.
I cannot even use the parameters of render_template() becuase the layout.html is not rendered anywhere in my app.py file

Normally, you'd have in your app.py a route that returns the template:
return render_template('child.html', data=data)
child.html extends layout.html.
data contains everything your template needs.
In your template, you'll have an if
{% if data.show_create_join_family %}

Related

Flask - Adding Parameter to Route Breaks Images

It seems I'm misunderstanding how the route in a Flask application is related to local files (images).
Basic example:
On the home page of my website (#main_bp.route('/index'), I have some content, including a navigation bar. The nav bar contains an image, call it logo.svg. The image in the nav bar always renders correctly on the home page ('/index').
The nav bar is rendered in base.html. The img src is ../static/images/logo.svg
I have another page, call it web_content/<content_number>.
In routes.py, it looks like this: #main_bp.route('/web_content/<content_number>', methods=['GET', 'POST'])
Images, including logo.svg in the nav bar, render just fine when I navigate to this page. This page uses {% extends 'base.html' %}
I'm trying to add a layer in my website, call it content_category. So, modified routes.py like this: #main_bp.route('/web_content/<content_category>/<content_number>
This page renders, so I believe my code in routes.py is OK (content_category is defined in the function, etc.) However, when I add the content_category parameter, the image in the nav bar breaks on the content page. If I go back to the home page, the image in the nav bar renders just fine. So it doesn't seem to be a global breakage, only on the /web_content page when I add in another parameter.
This is confusing to me because I define the nav bar in only 1 place, base.html, and if the images render in one place I expect them to render everywhere.
Using a path like ../static/images/logo.svg will make the browser load that image, relative to the path in the URL. By adding parameters like content_category this is changing that URL path.
Instead use Flask's url_for function, in your template, to render the correct path dynamically:
<img src="{{ url_for('static', filename='logo.svg') }}" />

Is there any way to implement list of different links in Flask application?

I am trying to create a blog page where my requirement is to list a group od links in a html page.
app.py:
#app.route("/blog")
def blog():
return render_template('blog.html')
blog.html:
{% extends "index.html" %}
{% block content %}
<ul>
<li>
Chapter 1
</li>
<li>
Chapter 2
</li>
<ul>
{% endblock content %}
Stored all my html pages in templates directory.
I am able to open the localhost:8000/blog where I can view all the Chapter1, chapter2 links, but when I click on the link I get error:
http://localhost:5000/templates/chapter%201.html
Not Found
The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
I am sure that this will not work as it is pointing to different URL, can some one guide how do I implement the list of Chapter in Flask app?
If you had the static html files already, you should serve it as static file as mentioned in document here. Then, put urls for these files in your main page:
url_for('static', filename='chapter1.html')
The templates directory is not linked to a URL, the files in that directory are not 'published'. You shouldn't put files there you intent to serve without processing (executing the templates).
With the default configuration only files in the static directory are accessible via the /static/ URL path prefix, see the Static Files section of the Flask Quickstart.
The intent for the templates directory is for the files to be loadable as Jinja2 templates using the render_template() function, where you use that function in endpoint functions you registered with Flask for specific URLs.
You may want to try out the Flask tutorial first, it covers both templates and static files in more detail.
For a blog site, the normal pattern would be for you to store the blog post data in a database or text files in some way Python can easily load, then use a single template to render the contents. You'd register a URL with a pattern, which would call a function that can load any blog page data, then use the blog page template to render the output:
#app.route('/blog/<page_name>')
def blog_page(page_name):
page_data = load_blog_page(page_name)
if not page_data: # no page? Produce a not found error.
abort(404)
return render_template('blog_page.html', **page_data)
The above function will be called when a browser visits URLs that start with /blog/, and is called with the next part as the page_name variable; e.g. /blog/chapter-1 would result in page_name being set to 'chapter-1'. Note that URLs can't have spaces in them (spaces would have to be encoded to %20 for the URL to still be a URL).
The function then loads the page data (with a load_log_page() function you'd have to write yourself), then provided page_data is not empty or None or some other false-y value indicating that the page doesn't actually exist, uses the render_template() function to produce HTML output. render_template() will use the file templates/blog_page.html as the template file here, and page_data is assumed to be a dictionary whose key-value pairs make the variables the template can use.

Extending a base tpl file and editing the body of it in bottle

I am familiar with flask, and trying hands on bottle module. I wanted to have a single base.tpl file which can have an editable body and the other tpl files could extend this base file and edit in its body to change the content. Like in flask, using jinja, we could use {% block bodyContent %}{% endblock %} and insert the html body content later when needed. How can we achieve the same with bottle module?
Bottle comes with jinja2 support, out of the box. Here's a toy example, just to illustrate. Note that you may prefer to use Bottle's jinja2_view rather than return a template directly.
from bottle import jinja2_template
app = Bottle()
home_template = '''
{{greeting}} - Thanks for stopping by.
'''
app.route('/')
def home():
return jinja2_template(home_template, greeting='Hello!')
You can find examples of more advanced usage here.
Actually bottle comes with this solution built into it's own template engine.
https://bottlepy.org/docs/dev/stpl.html#template-functions
include(sub_template, **variables)
Render a sub-template with the specified variables and insert the resulting text into the current template. The function returns a dictionary containing the local variables passed to or defined within the sub-template:
% include('header.tpl', title='Page Title')
Page Content
% include('footer.tpl')
rebase(name, **variables)
Mark the current template to be later included into a different template. After the current template is rendered, its resulting text is stored in a variable named base and passed to the base-template, which is then rendered. This can be used to wrap a template with surrounding text, or simulate the inheritance feature found in other template engines:
% rebase('base.tpl', title='Page Title')
<p>Page Content ...</p>
This can be combined with the following base.tpl:
<html>
<head>
<title>{{title or 'No title'}}</title>
</head>
<body>
{{!base}}
</body>
</html>

Frozen flask creates the files but gets the links wrong

Using frozen flask to make my website static, I have the following problem.
While all of my pages are being built (file//c:/correctpath/build/2014/page-title/index.html) the links to the pages are file:///c:/2014/page-title/.
Is there something I have missed?
EDIT:
In my template I have something like
{% for page in pages %}
{{ page.title }}
{% endfor %}
where .url() is a method on the page object:
return url_for('article', name=self.name, **kwargs)
url_for produces absolute paths (e. g. /2014/page-title) - when you open up your files in the browser it follows the rules regarding relative URL resolution and strips the extra file contents. If you just want to view your files as they will be seen on the server, Flask-Frozen has a run method that will let you preview your site after generating it.
Alternately, you can set FREEZER_RELATIVE_URLS to True to have Flask-Frozen generate links with index.html in them explicitly.
Rather than setting FREEZER_RELATIVE_URLS = True, with resulting URLs ending on index.html, you can also set FREEZER_BASE_URL to <http://your.website/subdir>.

How do you integrate HTML with Django?

I have an HTML file that has a web page design with a single form, for a user to enter his name. I want to create an six entry array for every submission (to later be filled with information on another page)
Is Django the proper utility to use for this? I would like to have the html design file and the python back end processing as separate files. If so, can anyone point me towards a good place to read about integrating HTML and underlying python codes that process HTML submission forms?
Django may be overkill for this. If all you want is a way to link a form to some backend Python code, a micro framework like Flask might be a better choice.
Here is how you do a simple form with Flask:
Create a directory project and inside it, a directory templates
Your template is simple:
{% if name %}
Hello {{ name }}
{% endif %}
<form method="POST">
<input type="text" name="name" value="Enter your name">
<input type="submit">
</form>
Save that as index.html in the templates subdirectory.
Create a file called go.py in the project directory, and in it copy and paste this:
from flask import Flask
from flask import render_template
from flask import request
app = Flask(__name__)
#app.route('/',methods=['POST','GET'])
def process_form():
if request.method == 'POST':
form_input = request.form['name']
return render_template('index.html',name=form_input)
else:
return render_template('index.html')
if __name__ == '__main__':
app.run(debug=True)
Finally from the project directory, type:
python go.py
Open your browser and go to http://localhost:5000/
You can create html form in Django, though you may have to convert the form to a template.
In case this you first time to use django, you may go though the official Django book
Django provides a template system (in which the presentation files are separate from the business logic and the entire system is highly decoupled). The template language is simple (but very powerful) text substitution on top of an existing text file. You can use the Django templates in HTML (full or partial), text, XML, JSON, or nearly any other text-based format.
Django also allows you to hook into another template system, but I don't know a lot about how that works.
Look at the Django template documentation for more information.

Categories