目次
テンプレートのダウンロード
今回はこちらのテンプレートを使用します
こちらのリンクの「Free Download」をクリックし、
テンプレートをダウンロードします
https://startbootstrap.com/themes/freelancer/
ダウンロード後はたくさんフォルダとファイルがありますが、
とりあえず必要なファイルはこちらだけです
templates/index.htmlへ適用する
先ほどダウンロードしたテンプレートのhtmlを
templates/index.htmlに貼り付けます
ちなみに今回作成しているFlaskのプロジェクトではblock contentの中に
htmlを入れてあげることで反映させることができます
1 2 3 4 5 6 7 |
{% extends "layout.html" %} {% block content %} <h1> Index page </h1> {% endblock %} |
貼り付け後はこのようなhtmlとなります
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
{% extends "layout.html" %} {% block content %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="description" content=""> <meta name="author" content=""> <title>Heroic Features - Start Bootstrap Template</title> <!-- Bootstrap core CSS --> <link href="vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <!-- Custom styles for this template --> <link href="css/heroic-features.css" rel="stylesheet"> </head> <body> <!-- Navigation --> <nav class="navbar navbar-expand-lg navbar-dark bg-dark fixed-top"> <div class="container"> <a class="navbar-brand" href="#">Start Bootstrap</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarResponsive"> <ul class="navbar-nav ml-auto"> <li class="nav-item active"> <a class="nav-link" href="#">Home <span class="sr-only">(current)</span> </a> </li> <li class="nav-item"> <a class="nav-link" href="#">About</a> </li> <li class="nav-item"> <a class="nav-link" href="#">Services</a> </li> <li class="nav-item"> <a class="nav-link" href="#">Contact</a> </li> </ul> </div> </div> </nav> <!-- Page Content --> <div class="container"> <!-- Jumbotron Header --> <header class="jumbotron my-4"> <h1 class="display-3">A Warm Welcome!</h1> <p class="lead">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsa, ipsam, eligendi, in quo sunt possimus non incidunt odit vero aliquid similique quaerat nam nobis illo aspernatur vitae fugiat numquam repellat.</p> <a href="#" class="btn btn-primary btn-lg">Call to action!</a> </header> <!-- Page Features --> <div class="row text-center"> <div class="col-lg-3 col-md-6 mb-4"> <div class="card h-100"> <img class="card-img-top" src="http://placehold.it/500x325" alt=""> <div class="card-body"> <h4 class="card-title">Card title</h4> <p class="card-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sapiente esse necessitatibus neque.</p> </div> <div class="card-footer"> <a href="#" class="btn btn-primary">Find Out More!</a> </div> </div> </div> <div class="col-lg-3 col-md-6 mb-4"> <div class="card h-100"> <img class="card-img-top" src="http://placehold.it/500x325" alt=""> <div class="card-body"> <h4 class="card-title">Card title</h4> <p class="card-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Explicabo magni sapiente, tempore debitis beatae culpa natus architecto.</p> </div> <div class="card-footer"> <a href="#" class="btn btn-primary">Find Out More!</a> </div> </div> </div> <div class="col-lg-3 col-md-6 mb-4"> <div class="card h-100"> <img class="card-img-top" src="http://placehold.it/500x325" alt=""> <div class="card-body"> <h4 class="card-title">Card title</h4> <p class="card-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sapiente esse necessitatibus neque.</p> </div> <div class="card-footer"> <a href="#" class="btn btn-primary">Find Out More!</a> </div> </div> </div> <div class="col-lg-3 col-md-6 mb-4"> <div class="card h-100"> <img class="card-img-top" src="http://placehold.it/500x325" alt=""> <div class="card-body"> <h4 class="card-title">Card title</h4> <p class="card-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Explicabo magni sapiente, tempore debitis beatae culpa natus architecto.</p> </div> <div class="card-footer"> <a href="#" class="btn btn-primary">Find Out More!</a> </div> </div> </div> </div> <!-- /.row --> </div> <!-- /.container --> <!-- Footer --> <footer class="py-5 bg-dark"> <div class="container"> <p class="m-0 text-center text-white">Copyright © Your Website 2019</p> </div> <!-- /.container --> </footer> <!-- Bootstrap core JavaScript --> <script src="vendor/jquery/jquery.min.js"></script> <script src="vendor/bootstrap/js/bootstrap.bundle.min.js"></script> </body> </html> {% endblock %} |
localhost:5000で確認すると
画像やcssがないので見た目も綺麗ではありません
※開発者ツールがわからないという方はこちらから調べてください
Web開発でよく使う、特に使えるChromeデベロッパー・ツールの機能
なので、次はcssを追加していきます
FlaskにCSSを追加する
FlaskにCSSを追加するにはstaticディレクトリを作成する必要があります
さらにその中にcssとjsディレクトリを作成します
ダウンロードしたテンプレートのフォルダに入っている
- vendor/bootstrap/cssの中身全部をstatic/cssへ
- vendor/bootstrap/jsの中身全部をstatic/jsへ
- css/heroic-features.cssをstatic/cssへ
ペーストする
このような内容となります
開発環境の違いで表示のされ方が異なるかもしれません
追加が完了したらbootstrapを読み込ませるために
templates/layout.htmlをこのように修正します
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> {# bootstrapの読み込み #} <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/bootstrap.min.css') }}"> <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/bootstrap-grid.css') }}"> <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/bootstrap-reboot.css') }}"> <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/heroic-features.css') }}"> <title>QA-Site</title> </head> <body> <ul> {# ログインしていれば表示 #} {% if current_user.is_authenticated %} <li><a href="{{ url_for('index') }}">Index</a></li> {#ここに追加#} <li><a href="{{ url_for('questions.find_all') }}">Questions</a></li> <li><a href="{{ url_for('auth.logout') }}">ログアウト</a></li> {% endif %} {#ログインしていなければ表示#} {% if not current_user.is_authenticated %} <li><a href="{{ url_for('auth.signup') }}">新規登録</a></li> <li><a href="{{ url_for('auth.login') }}">ログイン</a></li> {% endif %} </ul> {# flaskのメッセージを表示 #} {% with messages = get_flashed_messages() %} {% if messages %} <div> {{ messages[0] }} </div> {% endif %} {% endwith %} {% block content %} {% endblock %} {# bootstrapの読み込み #} <script type=text/javascript src="{{ url_for('static', filename='js/jquery.min.js') }}"></script> <script type=text/javascript src="{{ url_for('static', filename='js/bootstrap.bundle.min.js') }}"></script> </body> </html> |
その後flaskを再起動してlocalhost:5000で確認しましょう
先ほどよりかはだいぶ前進しました!
ルーティングやヘッダーを修正する
先ほどはtemplates/index.htmlにbootstrapのhtmlを追加しましたが、
今からlayout.htmlに移動してヘッダーに
- ログインしていれば「Questions」のリンクを表示
リンクを追加します。
修正後はtemplates/layout.htmlはこのようになります
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> {# bootstrapの読み込み #} <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/bootstrap.min.css') }}"> <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/bootstrap-grid.css') }}"> <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/bootstrap-reboot.css') }}"> <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/heroic-features.css') }}"> <title>QA-Site</title> </head> <body> <!-- Navigation --> <nav class="navbar navbar-expand-lg navbar-dark bg-dark fixed-top"> <div class="container"> <a class="navbar-brand" href="#">Start Bootstrap</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarResponsive"> <ul class="navbar-nav ml-auto"> <li class="nav-item active"> <a class="nav-link" href="{{ url_for('index') }}"> Home <span class="sr-only">(current)</span> </a> </li> {% if current_user.is_authenticated %} {#ここに追加#} <li class="nav-item"> <a class="nav-link" href="{{ url_for('questions.find_all') }}">Questions</a> </li> <li class="nav-item"> <a class="nav-link" href="{{ url_for('auth.logout') }}">ログアウト</a> </li> {% endif %} {#ログインしていなければ表示#} {% if not current_user.is_authenticated %} <li class="nav-item"> <a class="nav-link" href="{{ url_for('auth.signup') }}">新規登録</a> </li> <li class="nav-item"> <a class="nav-link" href="{{ url_for('auth.login') }}">ログイン</a> </li> {% endif %} </ul> </div> </div> </nav> <!-- Page Content --> <div class="container"> {# flaskのメッセージを表示 #} {% with messages = get_flashed_messages() %} {% if messages %} <div> {{ messages[0] }} </div> {% endif %} {% endwith %} {% block content %} {% endblock %} <!-- Jumbotron Header --> <header class="jumbotron my-4"> <h1 class="display-3">A Warm Welcome!</h1> <p class="lead">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsa, ipsam, eligendi, in quo sunt possimus non incidunt odit vero aliquid similique quaerat nam nobis illo aspernatur vitae fugiat numquam repellat.</p> <a href="#" class="btn btn-primary btn-lg">Call to action!</a> </header> <!-- Page Features --> <div class="row text-center"> <div class="col-lg-3 col-md-6 mb-4"> <div class="card h-100"> <img class="card-img-top" src="http://placehold.it/500x325" alt=""> <div class="card-body"> <h4 class="card-title">Card title</h4> <p class="card-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sapiente esse necessitatibus neque.</p> </div> <div class="card-footer"> <a href="#" class="btn btn-primary">Find Out More!</a> </div> </div> </div> <div class="col-lg-3 col-md-6 mb-4"> <div class="card h-100"> <img class="card-img-top" src="http://placehold.it/500x325" alt=""> <div class="card-body"> <h4 class="card-title">Card title</h4> <p class="card-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Explicabo magni sapiente, tempore debitis beatae culpa natus architecto.</p> </div> <div class="card-footer"> <a href="#" class="btn btn-primary">Find Out More!</a> </div> </div> </div> <div class="col-lg-3 col-md-6 mb-4"> <div class="card h-100"> <img class="card-img-top" src="http://placehold.it/500x325" alt=""> <div class="card-body"> <h4 class="card-title">Card title</h4> <p class="card-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sapiente esse necessitatibus neque.</p> </div> <div class="card-footer"> <a href="#" class="btn btn-primary">Find Out More!</a> </div> </div> </div> <div class="col-lg-3 col-md-6 mb-4"> <div class="card h-100"> <img class="card-img-top" src="http://placehold.it/500x325" alt=""> <div class="card-body"> <h4 class="card-title">Card title</h4> <p class="card-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Explicabo magni sapiente, tempore debitis beatae culpa natus architecto.</p> </div> <div class="card-footer"> <a href="#" class="btn btn-primary">Find Out More!</a> </div> </div> </div> </div> <!-- /.row --> </div> <!-- /.container --> <!-- Footer --> <footer class="py-5 bg-dark"> <div class="container"> <p class="m-0 text-center text-white">Copyright © Your Website 2019</p> </div> <!-- /.container --> </footer> {# bootstrapの読み込み #} <script type=text/javascript src="{{ url_for('static', filename='js/jquery.min.js') }}"></script> <script type=text/javascript src="{{ url_for('static', filename='js/bootstrap.bundle.min.js') }}"></script> </body> </html> |
templates/index.htmlは前の状態にひとまず戻します
1 2 3 4 5 6 7 |
{% extends "layout.html" %} {% block content %} <h1> Index page </h1> {% endblock %} |
この状態で、ログインしたりログアウトしてテストを行いましょう
ちなみにlayout.htmlへ直接貼り付けたので全ての要素がこのlayoutを反映していることになってます
これでどの画面からでもログインしたり、ログアウトしたりすることができます!
Questionsをリスト表示する
templates/questions/index.htmlの綺麗に表示されるようにしていきます
templates/questions/index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
{% extends "layout.html" %} {% block content %} <div class="container"> <header class="jumbotron my-4"> <h1 class="display-3">Questions</h1> <a class="btn btn-primary btn-lg" href="{{ url_for('questions.add') }}">質問する!</a> </header> <div class="row text-center"> {% for question in quesions %} <div class="col-lg-3 col-md-6 mb-4"> <div class="card h-100"> <img class="card-img-top" src="http://placehold.it/500x325" alt=""> <div class="card-body"> <h4 class="card-title">{{ question.title }}</h4> <p class="card-text">{{ question.body }}</p> </div> <div class="card-footer"> <a class="btn btn-primary" href="{{ url_for('questions.find_one', question_id=question.id) }}">詳細</a> </div> </div> </div> {% endfor %} </div> </div> {% endblock %} |
localhost:5000/questionsではこのように表示されています
ただし下の方にスクロールするとtemplates/layout.htmlのhtmlも表示されて
おかしなことになっているので、templates/layout.htmlを修正します
templates/layout.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> {# bootstrapの読み込み #} <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/bootstrap.min.css') }}"> <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/bootstrap-grid.css') }}"> <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/bootstrap-reboot.css') }}"> <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/heroic-features.css') }}"> <title>QA-Site</title> </head> <body> <!-- Navigation --> <nav class="navbar navbar-expand-lg navbar-dark bg-dark fixed-top"> <div class="container"> <a class="navbar-brand" href="#">Start Bootstrap</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarResponsive"> <ul class="navbar-nav ml-auto"> <li class="nav-item active"> <a class="nav-link" href="{{ url_for('index') }}"> Home <span class="sr-only">(current)</span> </a> </li> {% if current_user.is_authenticated %} {#ここに追加#} <li class="nav-item"> <a class="nav-link" href="{{ url_for('questions.find_all') }}">Questions</a> </li> <li class="nav-item"> <a class="nav-link" href="{{ url_for('auth.logout') }}">ログアウト</a> </li> {% endif %} {#ログインしていなければ表示#} {% if not current_user.is_authenticated %} <li class="nav-item"> <a class="nav-link" href="{{ url_for('auth.signup') }}">新規登録</a> </li> <li class="nav-item"> <a class="nav-link" href="{{ url_for('auth.login') }}">ログイン</a> </li> {% endif %} </ul> </div> </div> </nav> {# flaskのメッセージを表示 #} {% with messages = get_flashed_messages() %} {% if messages %} <div> {{ messages[0] }} </div> {% endif %} {% endwith %} {% block content %} {% endblock %} <!-- Footer --> <footer class="py-5 bg-dark"> <div class="container"> <p class="m-0 text-center text-white">Copyright © Your Website 2019</p> </div> <!-- /.container --> </footer> {# bootstrapの読み込み #} <script type=text/javascript src="{{ url_for('static', filename='js/jquery.min.js') }}"></script> <script type=text/javascript src="{{ url_for('static', filename='js/bootstrap.bundle.min.js') }}"></script> </body> </html> |
修正後はlayout.htmlの余分なhtmlを削除したので綺麗になっています
Questionsの詳細を修正する
Questionsの一覧は綺麗にしたので、次は詳細画面を綺麗にしていきます
templates/questions/show.htmlをこのように修正します
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
{% extends "layout.html" %} {% block content %} <div class="container"> <header class="jumbotron my-4"> <h1 class="display-3">{{ question.title }}</h1> </header> <div class="card-body"> 内容:<br> {{ question.body }} </div> <a href="{{ url_for('questions.find_all')}}">戻る</a> <a href="{{ url_for('questions.update', question_id=question.id) }}">修正</a> </div> {% endblock %} |
見た目はこのようになります
bootstrapの適用はこれで完了です
Bitbucketのリンク:https://bitbucket.org/Masahiro_Okubo/qa-site/src/phase2/
ブランチは「phase2」で指定してください。