テンプレートのダウンロード
今回はこちらのテンプレートを使用します
こちらのリンクの「Free Download」をクリックし、
テンプレートをダウンロードします
https://startbootstrap.com/themes/freelancer/
ダウンロード後はたくさんフォルダとファイルがありますが、
とりあえず必要なファイルはこちらだけです
templates/index.htmlへ適用する
先ほどダウンロードしたテンプレートのhtmlを
templates/index.htmlに貼り付けます
ちなみに今回作成しているFlaskのプロジェクトではblock contentの中に
htmlを入れてあげることで反映させることができます
{% extends "layout.html" %} {% block content %} <h1> Index page </h1> {% endblock %}
貼り付け後はこのようなhtmlとなります
{% 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をこのように修正します
<!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はこのようになります
<!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は前の状態にひとまず戻します
{% extends "layout.html" %} {% block content %} <h1> Index page </h1> {% endblock %}
この状態で、ログインしたりログアウトしてテストを行いましょう
ちなみにlayout.htmlへ直接貼り付けたので全ての要素がこのlayoutを反映していることになってます
これでどの画面からでもログインしたり、ログアウトしたりすることができます!
Questionsをリスト表示する
templates/questions/index.htmlの綺麗に表示されるようにしていきます
templates/questions/index.html
{% 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
<!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をこのように修正します
{% 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」で指定してください。
コメントを残す