today::エンジニアに憧れる非エンジニア

今のところは、エンジニアとは言えないところの職種です。しかしエンジニア的なものの考え方に興味津津。

Pythonあれこれ 2021-02-17 - Jinja2を使って、入力内容がPythonで処理されるWebページを作成する

概要

「Head First Python 第2版」を進めていった中で考えたことの記録です。

Head First Python 第2版 ―頭とからだで覚えるPythonの基本

Head First Python 第2版 ―頭とからだで覚えるPythonの基本

  • 作者:Paul Barry
  • 発売日: 2018/03/24
  • メディア: 単行本(ソフトカバー)

構築したいWebページはどのようなものか

入力フォーム.svg

↑入力フォームのイメージ

処理結果.svg

↑処理結果のイメージ

上述表示内容のWebページを得るために、以下3つのJinja2テンプレートを定義します。

  • ベーステンプレート
    • Webサイトのルック&フィールを定義する
  • 入力フォーム
  • 処理結果の表示

Jinja2とは

Flaskで用いられるテンプレートエンジンです。Flaskにおいては、以下の目的でJinja2テンプレートエンジンを用いています。

  • HTMLに、既存テンプレートを継承して用いる機能を追加する
  • PythonコードからHTMLの内容の一部を受け取る機能を追加する

jinja.palletsprojects.com

Webページのマークアップについて解説

ベーステンプレート

<!DOCTYPE html>
<html>
  <head>
    <title>{{ the_title }}</title>
    <link rel="stylesheet" href="static/hf.css">
  </head>
  <body>
    {% block body %}

    {% endblock %}
  </body>
</html>

他のHTMLファイルの内容をインポートして使うためのテンプレートです。解説は以下の通りです。

  • Webサイト全体に共通する内容についての記述である
  • 以下の内容のみが定義されている
    • DOCTYPE宣言
      • このHTMLが、HTML5標準に準拠するものであることを示す
    • HTML全体の基底要素であるhtml要素
    • head要素の記述
  • スタイルシートとしては、static/hf.cssというファイルの内容が用いられる
    • 同ファイルが必要である
  • body要素以下の内容は、他のHTMLファイルをインポートすることを前提とする
    • インポートされるHTMLファイルの内容は、{% block body %}から{% endblock %}までの間が置き換えられて埋め込まれる
  • 本ベーステンプレート自身は直接呼び出されない
    • 本ベーステンプレートの記述だけでは、完全な内容のHTMLは構築できない
    • 実際に呼び出されるのは、本ベーステンプレートを継承した各種テンプレートである

入力フォーム

{% extends 'base.html' %}

{% block body %}

<h2>{{ the_title }}</h2>

<form method='POST' action='/search4'>
<table>
  <p>このフォームを使って検索リクエストを送ってください。</p>
<tr><td>フレーズ:</td><td><input name='phrase' type='TEXT' width='60'></td></tr>
<tr><td>文字:</td><td><input name='letters' type='TEXT' value='aeiou'></td></tr>
</table>
<p>準備ができたら、以下のボタンを押してください。</p>
<p><input value='実行!' type='SUBMIT'></p>
</form>

{% endblock %}

入力フォームのHTMLマークアップの内容です。解説は以下の通りです。

  • 上述base.htmlを継承し、その中にインポートされる
    • {% block_body %}から{% endblock %}までの間が、entry.htmlの同内容に置き換えられる
  • Webページのタイトルは、Pythonコードによって与えられる
    • テンプレートの呼び出し元となるPythonの関数には、the_titleというキーワード引数が必要となる
  • 1つのHTMLフォームを定義している
    • 「実行!」ボタンがクリックされると、フォームの入力内容がHTTPのPOSTメソッドによって/search4というリソースに渡される
    • phraseという属性名で、文字列を内容とする属性を渡す
    • lettersという属性名で、文字列を内容とする属性を渡す
    • リソース/search4に割り付けられるアプリケーションには、以下の処理を行う機能が必要となる
      • POSTメソッドのリクエストを受け付ける機能
      • 属性名がphraseで、内容が文字列である属性を処理する機能
      • 属性名がlettersで、内容が文字列である属性を処理する機能

処理結果の表示

{% extends 'base.html' %}

{% block body %}

<h2>{{ the_title }}</h2>

<p>以下のデータを送信しました。</p>
<table>
<tr><td>フレーズ:</td><td>{{ the_phrase }}</td></tr>
<tr><td>文字:</td><td>{{ the_letters }}</td></tr>
</table>

<p>「{{ the_phrase }}から{{ the_letters }}」を検索すると、次の結果を返します。</p>
<h3>{{ the_results }}</h3>
{% endblock %}
  • 上述base.htmlを継承し、その中にインポートされる
    • {% block_body %}から{% endblock %}までの間が、entry.htmlの同内容に置き換えられる
  • Webページのタイトルは、Pythonコードによって与えられる
    • テンプレートの呼び出し元となるPythonの関数には、the_titleというキーワード引数が必要となる
  • 本文中に、Pythonコードによって与えられる表示内容が3つ定義されている
    • 具体的には以下の3つ
      • the_phrase
      • the_letters
      • the_results
    • テンプレートの呼び出し元となるPythonの関数には、以上3つのキーワード引数が必要となる