これは、エンジニア未経験のど素人が、終末エンジニアとして
PythonとFlaskでWebアプリを作成するためのメモ記事です。
ランディングページ
Flask
[flaskr起動&test編]更新予定
[Docker] (http://qiita.com/yuusei/items/51b3917f1ce3f2fbb5e6)
[Dockerコマンド]http://qiita.com/yuusei/items/640c85da1a1bf43fe72f
[Web開発]このページ
##Web開発の基礎知識メモ
・Webプログラミングは大きく分けて二つの領域がある#「サーバー」#と#「クライアント」#
・クライアント・サーバーモデル(C/S)において「サーバー」とは「サービスを提供するシステム」の事である
・クライアント・サーバーモデル(C/S)において「クライアント」とは「サービスを利用するシステム」の事である
・C/Sモデルに対してサーバーとクライアントの区別がないモデルをP2P(Peer to Peer)と言う
・C/Sはクライアントがサーバーにアクセスすると言う役割方式であるため、それぞれの役割に応じて別の言語を使い分けなければいけない
##Webサービスのディレクトリ構造メモ
・最適な構造なんてない。共通するのはRoot Directory( / )のみ
・構造はサービスに合わせてフレキシブルに
・ただし、基本は木構造。ごちゃごちゃすると後でえらいことになる
・Terminal上にディレクトリ構造を見るのはHomeBrewのtreeがわかりやすい
参考:Qiita:PythonのWebアプリケーション(Django)を初心者にもわかりやすく解説
HTMLについて
Webページは基本HTML言語で作成されています。
では、HyperTextMarkupLanguage(HTML)とは何か?
ここ を見る限り、基本はテキストであり、そこにHyperリンクを埋め込んだり、レイアウトを組んだり、多彩な書体/色の表現ができるようになっているものです。
それではFlaskのTutorialにある”layout.html”の中身を見て見ましょう。
lyaout.html
< title>Flaskr< /title>
< link rel=stylesheet type=text/css href="{{ url_for('static', filename='style.css') }}">
< div class=page>
< h1>Flaskr< /h1>
< div class=metanav>
{ % if not session.logged_in %}
< a href="{{ url_for('login') }}">log in< /a>
{ % else %}
< a href="{{ url_for('logout') }}">log out< /a>
{ % endif %}
< /div>
{ % for message in get_flashed_messages() %}
< div class=flash>{{ message }}
{ % endfor %}
{ % block body %}{% endblock %}
< /div>
多分、HTMLを描き慣れてる人にはすぐ分かる内容なんでしょうかね?
Flask・・・Pythonぽいなと言うところをいくつか書いていくと、
“{% if not session.logged_in %}”や”{% else %}”のように{% body %}部分ですね。
Pythonを使う利点と言うのはこのようにウェブページをプログラミング言語の様に扱って、
同じページを大量に生成するloop処理や、上記のようなif-els分岐でのログイン制御ができる。
そういったところなのでしょう。
##show.html
{ % extends "layout.html" %}
{ % block body %}
{ % if session.logged_in %}
< form action="{{ url_for('add_entry') }}" method=post class=add-entry>
< dl>
< dt>Title:
< dd>
< dt>Text:
< dd> < /textarea>
< dd>
< /dl>
< /form>
{ % endif %}
< ul class=entries>
{ % for entry in entries %}
< li>{{ entry.title }}
{{ entry.text|safe }}
{ % else %}
< li>Unbelievable. No entries here so far
{ % endfor %}
< /ul>
{ % endblock %}
ここに”{% for entry in entries %}”なるfor文が出てきました。
別途@appconfigで定義したDATABASEの中身、entriesを舐めていく感じです。
その後のelse文で、DBのエントリーを舐めつくしたら終わり。そんな感じのようです。
“{% extends "layout.html" %}”とあるように、これは “layout.html”の拡張用らしいです。
どのような仕組みなのか、いまいちわからない・・・
HTML5 クイックリファレンス(http://htmq.com/html5/)
ここでは上記のリンクページから”layout.html”に乗っているものを取り出します。
Html素人なので、知ってる人からするともどかしいと思いますし、
備忘録的なものなので分かっている人は無視してください。
ドキュメントタイプの宣言。この一文でHTML5だと言う事をブラウザに理解させることができる。HTML4.01はもっと長かったらしい。これがないとレイアウトが崩れる可能性があるため必ず入れましょう。
< title>Flaskr< /title>
ページのタイトル(複数ページを開いている時にTabに表示される文章)。SEO対策に使えるらしい。KeyWordはここに入れる?
< link rel=stylesheet type=text/css href="{{ url_for('static', filename='style.css') }}">
該当ページにリンクしている外部リソース(HTML/CSS/RSSなど)をここで宣言する。
“link”は”rel”と”href”との組み合わせで書く必要がある。
“rel”リンクの仕方を指定。属性には色々あるらしいのでこちら参照で 。今回はスタイルシートを指定しています。
“href”具体的なURLを指定。
ところでは
〜間に突っ込むのがルールなんですが、この”layout.html”には〜が無いような・・・< div class=page>
〜
< /div>
< div>はワイルドカード。< div>〜< /div>間に入れたものをひとかたまりのブロックとして扱える。
いわゆる便利タグだが、他に適切なタグがあるならそれを使う方が良い。メンテナンスをする際に見つけづらかったり、アクセス数に影響するかららしい。
ここではclass属性を指定している。
< h1>Flaskr< /h1>
見出しタグ。< h1>から< h6>まであるらしい。
< div class=metanav>
{ % if not session.logged_in %}
< a href="{{ url_for('login') }}">log in< /a>
{ % else %}
< a href="{{ url_for('logout') }}">log out< /a>
{ % endif %}
< /div>
さっきのclass属性内でさらにclass属性を使用。metanavとする。
metanavは単なる命名であり、特に深い意味がなさそう。
通常のHTMLではmetaタグは< head>〜< /head>内に突っ込むメタ情報タグの中で< div>〜< /div>の役割を果たす。
また、< nav>タグはページ内へのナビゲーションタグ。同じサイト内のURLのみ対象にする”link”だと思う。
ここでは、pythonのコードでログイン画面を表示するかログアウト画面を表示するかを指定している感じ。
< a href=“URL”>リンクの表示< /a>なるアンカータグを使って、ログインページとログアウトページを表示するようにしている。
< a href = “URL”>リンクの表示< /a>は検索エンジンにコンテンツの内容を渡すためのタグ。つまり、「リンクの表示」と言うところを書き換えればSEO対策に使える・・・らしい。
しかし、いちいちqiitaのHTMLコードと被るのはどうにかしてほしいな・・・回避しきれない
{% for message in get_flashed_messages() %}
{{ message }}
{% endfor %}
{% block body %}{% endblock %}
ここはほぼpython。class=flashで”message”をフラッシュで表示する。
以上が”layout.html”の内容。
続いて”show_entries.html”の内容。
{% extends "layout.html" %}
少し探しただけじゃわかんないんですが、
多分layoutが親、このshowが子として親子関係を宣言しているんだろうと。
{% block body %}
〜
{% endblock %}
本体(=body)の範囲を宣言。
{% if session.logged_in %}
< form action="{{ url_for('add_entry') }}" method=post class=add-entry>
< dl>
< dt>Title:
< dd>
< dt>Text:
< dd>
< dd>
< /dl>
< /form>
{ % endif %}
セッションにログインした場合、マイクロブログをエントリするための画面を表示する。
< ul class=entries>
{% for entry in entries %}
< li>< h2>{{ entry.title }}< /h2>{{ entry.text|safe }}
{ % else %}
< li>Unbelievable. No entries here so far< /em>
{ % endfor %}
< /ul>
entriesに入っている要素entryのすべてについて、< li>でリストの項目を記述する。
entriesには過去から最新まで全てが入っていると思われる。
それを< h2>レベルでtitleとtextを表示している。
表示するentryがなくなった場合、Unbelievable. No entrees here so far とタグ(emphasis)で強調して表示される。
最後に”login.html”の内容
コピペしたらHTMLソースだからUIが表示された。 必要な部分だけ抜き出す
今までにないところだと・・・
<dl>
<dt>Username:
<dd><input type=text name=username>
<dt>Password:
<dd><input type=password name=password>
<dd><input type=submit value=Login>
</dl>
こことか大事そうですかね。
調べてみると < dl >の中で< dt >を定義し、
その説明を< dd >として表示するようです。
これ、多分ユーザー名とパスワードをsqlテーブルに紐づけるために必要なんだと思うのですが、
あれですかね。Passwordに< dd >が二つアサインされているのは、お約束なんですかね?
いまいちわからない。。。
CSS = スタイルシートの定義
サービス全体の基礎フォントなどを
作成済みの static フォルダに style.css という名前でスタイルシート作成します。
body { font-family: sans-serif; background: #eee; }
a, h1, h2 { color: #377BA8; }
h1, h2 { font-family: 'Georgia', serif; margin: 0; }
h1 { border-bottom: 2px solid #eee; }
h2 { font-size: 1.2em; }
.page { margin: 2em auto; width: 35em; border: 5px solid #ccc;
padding: 0.8em; background: white; }
.entries { list-style: none; margin: 0; padding: 0; }
.entries li { margin: 0.8em 1.2em; }
.entries li h2 { margin-left: -1em; }
.add-entry { font-size: 0.9em; border-bottom: 1px solid #ccc; }
.add-entry dl { font-weight: bold; }
.metanav { text-align: right; font-size: 0.8em; padding: 0.3em;
margin-bottom: 1em; background: #fafafa; }
.flash { background: #CEE5F5; padding: 0.5em;
border: 1px solid #AACBE2; }
.error { background: #F0D6D6; padding: 0.5em; }
CSSってスタイルシートだったんですね
CSSは仕様書みたいなもんですかね。全体感を定義しているようです。
以下、随時追加予定