(三)flask搭建博客系列之BootStrap

本篇博客介绍flask中Bootstrap的使用,因为前端页面编写不是我们的主要目标,这里仅提供一些简陋的页面以作参考。
本篇博客参考内容:
https://github.com/greyli/bluelog
https://www.cnblogs.com/hippieZhou/p/10593552.html

1.相关库安装

pip install bootstrap-flask

2.相关代码

在extensions.py中添加bootstrap的实例:

from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_bootstrap import Bootstrap

db = SQLAlchemy()
migrate = Migrate()
bootstrap = Bootstrap()

__init__.py中的初始化代码修改如下:

from flask import Flask

from myblog.home.blog import blog_bp
from myblog.extensions import db, migrate, bootstrap
from myblog.config import Config


def create_app():
    app = Flask(__name__)
    app.config.from_object(Config)

    register_blueprints(app)
    register_extensions(app)

    return app


def register_blueprints(app):
    app.register_blueprint(blog_bp)


def register_extensions(app):
    db.init_app(app)
    db.create_all(app=app)
    migrate.init_app(app, db)
    bootstrap.init_app(app)

blog.py中的视图函数修改如下:

from flask import request, Blueprint, render_template

from myblog.models import Article, Category, Comment
from myblog.utils import fake_all


blog_bp = Blueprint('blog', __name__)


@blog_bp.route('/') 
@blog_bp.route('/index')            
def index(): 
    page = request.args.get('page', 1, type=int)
    articles = Article.query.order_by(Article.timestamp.desc()).paginate(page, 5, False)

    categories = Category.query.all()

    return render_template('blog/index.html', articles=articles, categories=categories)


@blog_bp.route('/article/<int:article_id>')            
def article(article_id): 
    article = Article.query.filter(Article.id == article_id).first()

    return render_template('blog/article.html', article=article)


@blog_bp.route('/category/<int:category_id>')            
def category(category_id): 
    page = request.args.get('page', 1, type=int)
    articles = Article.query.filter(Article.category_id==category_id).order_by(Article.timestamp.desc()).paginate(page, 5, False)

    return render_template('blog/category.html', articles=articles, category_id=category_id)

3.页面编写

在templates目录下新建base.html(存放公用的导航栏和加载bootstrap等)、新建blog文件夹,在blog文件夹下新建index.html、article.html、category.html,分别为博客首页、文章内容页、文章分类页,其中博客首页和文章分类页使用paginate实现了分页效果。

在static目录下添加一个网站的ico格式图片资源,取名为 favicon.ico,整个目录结构变更如下:

base.html:

<!DOCTYPE html>
<html lang="en">

<head>
    {% block head %}
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> 
        {% block styles %}
            <link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}"> {{ bootstrap.load_css() }} 
        {% endblock %} 
        <title>{% block title %}{% endblock %}</title>
    {% endblock %}
</head>

<body>
    {% block nav %}
        <nav class="navbar navbar-expand-lg navbar-light bg-light">
            <div class="container">
                <a class="navbar-brand" href="#">我的博客</a>
        
                <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
                        <span class="navbar-toggler-icon"></span>
                    </button>
        
                <div class="collapse navbar-collapse" id="navbarSupportedContent">
                    <ul class="navbar-nav mr-auto">
                        <li class="nav-item {% if request.endpoint == 'blog.index' %} active {% endif %}">
                            <a class="nav-link" href="{{ url_for('blog.index') }}">首页<span class="sr-only">(current)</span></a>
                        </li>
                    </ul>
        
                    <ul class="navbar-nav">
                        <li class="nav-item {% if request.endpoint == 'blog.index' %} active {% endif %}">
                            <a class="nav-link" href="{{ url_for('blog.index') }}">登录</a>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>
    {% endblock nav %}

    <div class="container">
        {% block content %}{% endblock%}
    </div>

    {% block scripts %}
        {{ bootstrap.load_js() }} 
    {% endblock %}

</body>

</html>

index.html:

{% extends 'base.html' %}

{% block title %}
Index
{% endblock %}

{% block content %}
    <div class="row">
        <div class="col-sm-8">
            {% for article in articles.items %}
            <br />
            <div class="alert alert-warning">
                <h4 class="text-primary">
                    <a href="{{ url_for('blog.article', article_id=article.id) }}">{{ article.title }}</a>
                </h4>
                <blockquote>
                    <small>
                        <strong>Category: </strong><a href="{{ url_for('blog.category', category_id=article.category.id) }}">{{ article.category.name }}</a>
                        <span class="float-right">{{ article.timestamp }}</span>
                    </small>   
                </blockquote>
            </div>
            {% endfor %}
            
            <nav aria-label="Page navigation example" class="m-4">
                <ul class="pagination justify-content-center">
                    <li class="page-item {% if not articles.has_prev %}disabled{% endif %}">
                        <a class="page-link" href="{{ url_for('blog.index', page=articles.prev_num) }}">上一页</a>
                    </li>

                    {% for page in articles.iter_pages(1,1,3,2) %} 
                        {% if page %}
                        <li class="page-item {%if page==articles.page%}active{%endif%}">
                            <a class="page-link" href="{{ url_for('blog.index',page=page) }}">{{page}}</a>
                        </li>
                        {% else %}
                        <li class="page-item disabled">
                            <a class="page-link" href="#">&hellip;</a>
                        </li>
                        {% endif %} 
                    {% endfor %}

                    <li class="page-item {% if not articles.has_next %}disabled{% endif %}">
                        <a class="page-link" href="{{ url_for('blog.index',page=articles.next_num) }}">下一页</a>
                    </li>
                </ul>
            </nav>
        </div>

        <div class="col-sm-4 sidebar">
            <br />
            <div class="card mb-3">
                <div class="card-header">Categories</div>
                <ul class="list-group list-group-flush">
                    {% for category in categories %}
                        <li class="list-group-item  list-group-item-action d-flex justify-content-between align-items-center">
                            <a href="{{ url_for('blog.category', category_id=category.id) }}">
                                {{ category.name }}
                            </a>
                            <span class="badge badge-primary badge-pill"> {{ category.articles|length }}</span>
                        </li>
                    {% endfor %}
                </ul>
            </div>
        </div>
    </div>

{% endblock %}

article.html:

{% extends 'base.html' %}

{% block title %}
Article
{% endblock %}

{% block content %}
    <br />
    <div class="alert alert-warning">
        <h4 class="text-primary">{{ article.title }}</h4>
        <br />
        {{ article.body }}
        <br />
        <br />
        <blockquote>
            <small>
                <strong>Category: </strong><a href="{{ url_for('blog.category', category_id=article.category.id) }}">{{ article.category.name }}</a>
                <span class="float-right">{{ article.timestamp }}</span>
            </small>   
        </blockquote>
    </div>
{% endblock %}

category.html:

{% extends 'base.html' %}

{% block title %}
Category
{% endblock %}

{% block content %}
<div class="col-sm-8">
    {% for article in articles.items %}
    <br />
    <div class="alert alert-warning">
        <h4 class="text-primary">
            <a href="{{ url_for('blog.article', article_id=article.id) }}">{{ article.title }}</a>
        </h4>
        <blockquote>
            <small>
                <strong>Category: </strong><a href="{{ url_for('blog.category', category_id=article.category.id) }}">{{ article.category.name }}</a>
                <span class="float-right">{{ article.timestamp }}</span>
            </small>   
        </blockquote>
    </div>
    {% endfor %}
    
    <nav aria-label="Page navigation example" class="m-4">
        <ul class="pagination justify-content-center">
            <li class="page-item {% if not articles.has_prev %}disabled{% endif %}">
                <a class="page-link" href="{{ url_for('blog.category', page=articles.prev_num,category_id=category_id) }}">上一页</a>
            </li>

            {% for page in articles.iter_pages(1,1,3,2) %} 
                {% if page %}
                <li class="page-item {%if page==articles.page%}active{%endif%}">
                    <a class="page-link" href="{{ url_for('blog.category',page=page,category_id=category_id) }}">{{page}}</a>
                </li>
                {% else %}
                <li class="page-item disabled">
                    <a class="page-link" href="#">&hellip;</a>
                </li>
                {% endif %} 
            {% endfor %}

            <li class="page-item {% if not articles.has_next %}disabled{% endif %}">
                <a class="page-link" href="{{ url_for('blog.category',page=articles.next_num,category_id=category_id) }}">下一页</a>
            </li>
        </ul>
    </nav>
</div>
{% endblock %}

整个博客网站的效果如下所示:
首页:

分类页:

文章详情页:

posted @ 2020-09-28 15:13  qxcheng  阅读(691)  评论(0编辑  收藏  举报