Tutorial : Sử dụng flask cho người mới bắt đầu ( Phần 2)

Tiếp theo phần 1 giới thiệu Flask trong bài này tôi sẽ giới thiệu cách tạo template cho framework Flask.

Cấu trúc đơn giản của Flask:

     microblog\
      flask\
        <virtual environment files>
      app\
        static\
        templates\
        __init__.py
        views.py
      tmp\
      run.py

Chúng ta sẽ phát triển trang home của microblog, Bạn có thể tạo ra 1 trang Home:

from app import app

@app.route('/')
@app.route('/index')
def index():
    user = {'nickname': 'Haink'}  # fake user
    return '''
<html>
  <head>
    <title>Home Page</title>
  </head>
  <body>
    <h1>Hello, ''' + user['nickname'] + '''</h1>
  </body>
</html>

Việc giữ cho các logic của ứng dụng tách biệt sẽ tốt hơn với template. giống như việc bạn có thể truyền các tham số cho template để hiển thị theo mong muốn. template đầu tiên của ứng dụng sẽ hiện thị home. (file app/templates/index.html):

<html>
  <head>
    <title>{{ title }} - microblog</title>
  </head>
  <body>
      <h1>Hello, {{ user.nickname }}!</h1>
  </body>
</html>

Bạn có thể thấy phần tĩnh của trang web sẽ chỉ khác nhau với mỗi người dùng sẽ nằm trong {{ ... }}. Bây giờ chúng ta sẽ sử dụng template này từ view. Một số framework phần view giống Controller trong MVC (file app/view.py):

from flask import render_template
from app import app

@app.route('/')
@app.route('/index')
def index():
    user = {'nickname': 'Haink'}  # fake user
    return render_template('index.html',
                           title='Home',
                           user=user)

Đến đây nếu bạn muốn gọi 1 trang HTML cùng với trang home hoặc 1 trang ban đầu, để làm điều đó bạn gọi tới hàm render_template từ Flask. render_template sẽ sử dụng định dạng Jinja2 để tạo ra template.

Điều khiển các biến

Jinja2 giúp điều khiển các biến, đưa nó vào trong {%...%}. chúng ta sẽ add biến vào template của file index (file app/templates/index.html):

<html>
  <head>
    {% if title %}
    <title>{{ title }} - microblog</title>
    {% else %}
    <title>Welcome to microblog</title>
    {% endif %}
  </head>
  <body>
      <h1>Hello, {{ user.nickname }}!</h1>
  </body>
</html>

Bây giờ template đã thông minh hơn. Thay vì hiện thị tĩnh ta sẽ truyền các biến title từ view.

Vòng lặp trong template
Trang blog của bạn sẽ follow các bloger khác, khi đó bạn muốn nhìn thấy các trang blog khác từ trang home qua recent posts. Chúng ta sẽ tạo ra các các bài post đó từ trong view.

def index():
    user = {'nickname': 'Haink'}  # fake user
    posts = [  # fake array of posts
        {
            'author': {'nickname': 'lucy'},
            'body': 'Beautiful day in Portland!'
        },
        {
            'author': {'nickname': 'thuy'},
            'body': 'The Avengers movie was so cool!'
        }
    ]
    return render_template("index.html",
                           title='Home',
                           user=user,
                           posts=posts)

Bên phần template chúng ta sẽ render và hiển thị author và body:

<html>
  <head>
    {% if title %}
    <title>{{ title }} - microblog</title>
    {% else %}
    <title>Welcome to microblog</title>
    {% endif %}
  </head>
  <body>
    <h1>Hi, {{ user.nickname }}!</h1>
    {% for post in posts %}
    <div><p>{{ post.author.nickname }} says: <b>{{ post.body }}</b></p></div>
    {% endfor %}
  </body>
</html>

Template kế thừa
Trong trang Home chúng ta cần chia tách thành các phần như nađvigation bar ở phần trên đầu hay các phần logo, đăng nhập, đăng kí, edit profile. Chúng ta có thể tạo các thành phần trên vào trang index, nhưng những trang khác cũng cần có các thành phần đó. Lúc này việc đưa các thành phần này vào một trang base và kế thừa lại ở những trang khác là cần thiết. Tôi sẽ tạo ra trang base (file app/templates/base.html):

<html>
  <head>
    {% if title %}
    <title>{{ title }} - microblog</title>
    {% else %}
    <title>Welcome to microblog</title>
    {% endif %}
  </head>
  <body>
    <div>Microblog: <a href="/index">Home</a></div>
    <hr>
    {% block content %}{% endblock %}
  </body>
</html>

Mỗi lần cần sử dụng các thành phần ở trang base chúng ta sẽ gọi tới nó. Như trang index (file app/templates/index.html):

{% extends "base.html" %}
{% block content %}
    <h1>Hi, {{ user.nickname }}!</h1>
    {% for post in posts %}
    <div><p>{{ post.author.nickname }} says: <b>{{ post.body }}</b></p></div>
    {% endfor %}
{% endblock %}

Tổng kết
Bây giờ bạn có thể chạy server và mở localhost:5000 và xem ứng dụng blog của mình. Trong bài sau tôi sẽ hướng dẫn các bạn về webform trong Flask.