テンプレートのダウンロード
今回はこちらのテンプレートを使用します
こちらのリンクの「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」で指定してください。









コメントを残す