zoukankan      html  css  js  c++  java
  • 狼书第三章Jinja2模板总结

    不得不说这一张给了我很大的帮助和启发,所以这一篇的总结我会好好的写,不单单是书上的内容,更多是我的个人思路和理解

    首先给出全部的app.py的代码顺着代码代入思路和知识点

    import os
    from flask import Flask, render_template, flash, redirect, url_for, Markup
    
    app = Flask(__name__)
    app.secret_key = os.getenv('SECRET_KEY', 'secret string')
    app.jinja_env.trim_blocks = True
    app.jinja_env.lstrip_blocks = True
    
    user = {
        'username': 'Grey Li',
        'bio': 'A boy who loves movies and music.',
    }
    
    movies = [
        {'name': 'My Neighbor Totoro', 'year': '1988'},
        {'name': 'Three Colours trilogy', 'year': '1993'},
        {'name': 'Forrest Gump', 'year': '1994'},
        {'name': 'Perfect Blue', 'year': '1997'},
        {'name': 'The Matrix', 'year': '1999'},
        {'name': 'Memento', 'year': '2000'},
        {'name': 'The Bucket list', 'year': '2007'},
        {'name': 'Black Swan', 'year': '2010'},
        {'name': 'Gone Girl', 'year': '2014'},
        {'name': 'CoCo', 'year': '2017'},
    ]
    
    
    @app.route('/watchlist')
    def watchlist():
        return render_template('watchlist.html', user=user, movies=movies)
    
    
    @app.route('/')
    def index():
        return render_template('index.html')
    
    
    # register template context handler
    #自定义上下文变量,返回值必须为字典
    @app.context_processor
    def inject_info():
        foo = 'I am foo.'
        return dict(foo=foo)  # equal to: return {'foo': foo}
    
    
    # register template global function
    #自定义全局函数
    @app.template_global()
    def bar():
        return 'I am bar.'
    
    
    # register template filter
    @app.template_filter()
    def musical(s):
        return s + Markup(' ♫')
    
    
    # register template test
    @app.template_test()
    def baz(n):
        if n == 'baz':
            return True
        return False
    
    
    @app.route('/watchlist2')
    def watchlist_with_static():
        return render_template('watchlist_with_static.html', user=user, movies=movies)
    
    
    # message flashing
    @app.route('/flash')
    def just_flash():
        flash('I am flash, who is looking for me?')
        return redirect(url_for('index'))
    
    
    # 404 error handler
    @app.errorhandler(404)
    def page_not_found(e):
        return render_template('errors/404.html'), 404
    
    
    # 500 error handler
    @app.errorhandler(500)
    def internal_server_error(e):
        return render_template('errors/500.html'), 500
    
    app.run(debug=True)
    

     首先创建一个实例

    将用户列表和电影的信息全部传到一个新的url中,在新的url中去返回一个html页面,来输出这些信息

    所以这里就新建了一个watchlist.html,这个html的目的就是为了返回url对应视图函数传入的内容

    watchlist.html的代码

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>{{user.username}}'s Watchlist</title>
    </head>
    <body>
    
    <a href="{{ url_for('index') }}">← Return</a>
    <h2>{{user.username}}</h2>
    
    {% if user.bio %}
        <i>{{user.boio}}</i>
    {% else %}
        <i>This user has not provided a bio.</i>
    {% endif %}
    
    <h5>{{ user.username }}'s Watchlist ({{movies | length}}):</h5>
    <ul>
        {% for movie in movies %}
            <li>{{movie.name}} - {{movie.year}}</li>
        {% endfor%}
    </ul>
    
    </body>
    </html>
    

    主要有俩个知识点,也就Jinja2模板中常用的语法,for循环和if判断

    唯一值得注意的就是要对应开始就要对应结束

    {% if xxx %} -----{% endif %}

    {% for xxx %} ----{% endfor %}

    模板中的变量,需要视图函数导入

    然后在根据代码流程分析:

    1.上下文变量:

    上下文变量是在模块中可以直接使用的,相当于模块中的全局变量。

    自定义上下文变量是利用装饰器@app.context_processor

    (1)@app.context_processor

    def xxx():

      pass

    (2)当然还有先定义函数,然后将函数以方法的方式去返回

    def xxx():

      pass

    app.context_processor(xxx)

    2.全局函数:全局函数就相当于是所有模块都可以使用的.

    自定义全局函数是利用装饰器:@app.template_global:

    3.过滤器:模板中的工具,操作对象|过滤方法(例如在watchlist.html{{movies|length}})计算这个movies有多长

    4.测试器:测试器从字面理解就是用来判断和对比测试

    关键装饰器@app.templat_text(),像下面这个例子的意思就是给baz函数传入参数,进行对比,再根据对比来返回结果

    5.基模板:来到Jinja2的灵魂之处了

    基模板的意思,通俗去理解就是共享块

    而块的概念就是将一个模板分成若干个块

    <!DOCTYPE html>
    <html>
    <head>
        {% block head %}
            <meta charset="utf-8">
            <title>{% block title %}Template - HelloFlask{% endblock %}</title>
            <link rel="icon" type="image/x-icon" href="{{ url_for('static', filename='favicon.ico') }}">
            {% block styles %}
                <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='style.css' ) }}">
            {% endblock %}
        {% endblock %}
    </head>
    <body>
    <nav>
        <ul><li><a href="{{ url_for('index') }}">Home</a></li></ul>
    </nav>
    
    <main>
        {% for message in get_flashed_messages() %}
            <div class="alert">{{ message }}</div>
        {% endfor %}
        {% block content %}{% endblock %}
    </main>
    <footer>
        {% block footer %}
            <small> © 2018 <a href="http://greyli.com" title="Written by Grey Li">Grey Li</a> /
                <a href="https://github.com/greyli/helloflask" title="Fork me on GitHub">GitHub</a> /
                <a href="http://helloflask.com" title="A HelloFlask project">HelloFlask</a>
            </small>
        {% endblock %}
    </footer>
    {% block scripts %}{% endblock %}
    </body>
    </html>
    

     从上述代码分析

    {%block head%} 中有俩个块

    一个是{%block title%}放置标题,

    另外一个是{%block style%}用来存放读取css链接的块,每个块结束,都要对应的使用{%endblcok%}这个关键字来结束块。

    在<body>这个标签中首先有一个Home跳转小按钮,跳转到主页,

    紧接着在<main>的标签中读取消息闪现中的消息,并存放了{%block content%}的信息,方便子模块继承

    在<footer>标签中创建{%block footer%}这个块,用来存放页脚信息。

    最后一个块就是{%block script%}用来放置js脚本链接的块

    6.子模版的继承问题

    子模版的只要是继承了基模块,那么在模板就开始要使用extend '基模板名',

    并且在写入内容或者修改内容的时候,必须是在主模块的已经定义了块中进行操作,

    如{%block content%} xxx {%endblock%},中间的内容就是子模块新增的。

    7.加载静态文件(js.css.img)

    使用<link>标签来加载静态文件,在{%block style%}中加载css文件,在{%block scripts%}中加载js文件,如下所示

    8.宏

    9.宏加载静态文件

    10.加载Favion:网页有一个小图标

    在模块中直接使用link标签,留意标签属性和文件选择

  • 相关阅读:
    学习bootsect.s中经常会问到的问题
    c++资源之不完全导引(全文) (转载)
    bootsect.S (读核笔记系列)
    WAP开发FAQ
    学习使用groovy(翻译稿之第一章)
    "革命尚未成功,同志仍需努力!"
    JAVA中this用法小结(转)
    Android <Button>样式的设置方法
    最新SDK android开发环境搭建
    Android中的数据存取(一)Preference
  • 原文地址:https://www.cnblogs.com/dachang/p/11189416.html
Copyright © 2011-2022 走看看