<jupyter_start><jupyter_text>Chapter 3. Basic Templates and Views 3.1 Introduction 3.1.1 Project "Thermos"Social bookmarking site 3.1.2 An index page(1) Generate HTML with Jinja2 template engine(2) Add styling (CSS) using static content 3.1.3 A simple form for adding bookmarks(1) Just HTML, no back-end logic yet(2) Uniform styling for both pages with template inheritance(3) Create maintainable links with `url_for`. 3.1.4 Custom error pages 3.2 Demo: starting a projectGo to http://www.initializr.com for simple responsive HTML5 Boilerplate.<jupyter_code># SAVE AS thermos.py.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from flask import Flask, render_template, url_for

app = Flask(__name__)

@app.route('/')
@app.route('/index')
def index():
    return render_template('index.html')
    
if __name__ == '__main__':
    app.run()<jupyter_output>* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)<jupyter_text>(1) To debug flask,```pythonapp.run(debug=True)```(2) Fix the references to css and js files. 3.3 Review: debug mode and render_template 3.3.1 Application object```pythonapp = Flask(__name__)``` 3.3.2 Run with debugging```pythonapp.run(debug=True)``` 3.3.3 Rendering a template<jupyter_code>import flask
help(flask.render_template)<jupyter_output>Help on function render_template in module flask.templating:

render_template(template_name_or_list, **context)
    Renders a template from the template folder with the given
    context.
    
    :param template_name_or_list: the name of the template to be
                                  rendered, or an iterable with template names
                                  the first one existing will be rendered
    :param context: the variables that should be available in the
                    context of the template.<jupyter_text>(1) HTML templates by default are in the directory `templates`.(2) Don't forget to return the result of render_template as the HTTP response otherwise you will get an Internal Server error. 3.4 Demo: HTML templates with Jinja2 3.4.1 Pass string parameters to the template via Jinja2.In `index.html`:```html......                                                                                Welcome                        pytwis is a simple twitter clone powered by python, flask, and redis.                                                                Title: {{ title }}                        Text: {{ text }}                    ......```<jupyter_code># SAVE AS thermos.py.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from flask import Flask, render_template, url_for

app = Flask(__name__)

@app.route('/')
@app.route('/index')
def index():
    return render_template('index.html', title='Title passed from view to template', text='Text passed from view to template')
    
if __name__ == '__main__':
    app.run()<jupyter_output><empty_output><jupyter_text>3.4.2 Pass a list to the template via Jinja2.In `index.html`:```html......                                                                                Welcome                        pytwis is a simple twitter clone powered by python, flask, and redis.                                                                Title: {{ title }}                        Text: {{ text[1] }}                    ......```<jupyter_code># SAVE AS thermos.py.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from flask import Flask, render_template, url_for

app = Flask(__name__)

@app.route('/')
@app.route('/index')
def index():
    return render_template('index.html', 
                           title='Title passed from view to template', 
                           text=['first', 'second', 'third'])
    
if __name__ == '__main__':
    app.run()<jupyter_output><empty_output><jupyter_text>3.4.3 Pass an object to the template via Jinja2.In index.html```html......                                                                                Welcome                        pytwis is a simple twitter clone powered by python, flask, and redis.                                                                Title: {{ title }}                        Text: {{ user.firstname }} {{ user.lastname }}                    ......```<jupyter_code># SAVE AS thermos.py.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from flask import Flask, render_template, url_for

class User:
    def __init__(self, firstname, lastname):
        self.firstname = firstname
        self.lastname = lastname
        
    def initials(self):
        return "{}. {}.".format(self.firstname[0], self.lastname[0])

app = Flask(__name__)

@app.route('/')
@app.route('/index')
def index():
    return render_template('index.html', 
                           title='Title passed from view to template', 
                           user=User('Wei', 'Ren'))
    
if __name__ == '__main__':
    app.run()<jupyter_output><empty_output><jupyter_text>3.5 Review: Jinja2 basics(1) `{{ var }}` renders value of var```pythonrender_template(index.html, var="hello")```(2) Dot notation: `{{ var.x }}`* Lookup an attribute `x` on `var`.* Lookup an item `x` in `var`.* Not found? Empty output.(3) We can call functions on objects as well:`{{ var.fn() }}` can pass arguments 3.6 Demo: Use url_for to generate links(1) Create a new simple template page add.html with no style.(2) Add the view for handling the route "/add".(3) Use `url_for` to create a URL link at index.html.<jupyter_code># SAVE AS thermos.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from flask import Flask, render_template, url_for

class User:
    def __init__(self, firstname, lastname):
        self.firstname = firstname
        self.lastname = lastname
        
    def initials(self):
        return "{}. {}.".format(self.firstname[0], self.lastname[0])

app = Flask(__name__)

@app.route('/')
@app.route('/index')
def index():
    return render_template('index.html', 
                           title='Title passed from view to template', 
                           user=User('Wei', 'Ren'))
    
@app.route('/add')
def add():
    return render_template('add.html')
    
if __name__ == '__main__':
    app.run()<jupyter_output><empty_output><jupyter_text>3.7 Template inheritance(1) Create a new template called `base.html` which can be regarded as the parent template of all templates.(2) Modify `index.html` and `add.html` to **extend** from `base.html`. 3.8 Review: Maintainable links with `url_for`(1) `url_for(view)`* Generates a URL to the given view* Can pass arguments to the view(2) `url_for` is available in template context.(3) Why use `url_for` instead of a simple link?* More maintainable: URL is only defined in `@app.route` call.* Handles escaping of special characters and Unicode data transparently.(4) Use `url_for` for all the static content.```python>>> from thermos import app>>> app.url_mapMap([ index>,  add>,  index>, ' (HEAD, GET, OPTIONS) -> static>])```For the static content, `url_for` will reverse the mapping from the files to the endpoint `static`. 3.8 Review: Template inheritance(1) `{% extends "base.html" %}`* Extend a base template* Must be first tag(2) `{% block content %}...{% endblock %}`Defines a block that can be overridden by child templates 3.9 Demo: Custom error pagesMake a copy of `404.html` and replace the error message in `404.html` by the one for the error code `500`.<jupyter_code># SAVE AS thermos.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from flask import Flask, render_template, url_for

class User:
    def __init__(self, firstname, lastname):
        self.firstname = firstname
        self.lastname = lastname
        
    def initials(self):
        return "{}. {}.".format(self.firstname[0], self.lastname[0])

app = Flask(__name__)

@app.route('/')
@app.route('/index')
def index():
    return render_template('index.html', 
                           title='Title passed from view to template', 
                           user=User('Wei', 'Ren'))
                           
@app.route('/add')
def add():
    return render_template('add.html')
    
@app.errorhandler(404):
def page_not_found(e):
    return render_template('404.html'), 404
    
@app.errorhandler(500):
    return render_template('505.html'), 500  
  
if __name__ == '__main__':
    app.run()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12435045317220544, 'fraction_numerical': 0.016555891238670694, 'mean_word_length': 2.524701873935264, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 38, 'https://': 0, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 1, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 17, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '150892', 'license': 'Apache-2.0', 'n_tokens_mistral': 2489, 'n_tokens_neox': 2348, 'n_words': 781, 'path': 'python/pluralsight-intro2flask/ch03-BasicTemplatesAndViews.ipynb', 'repo_name': 'renweizhukov/learning-ml', 'size': '8275'}