├── tests ├── __init__.py ├── test_bootstrap4 │ ├── __init__.py │ ├── test_render_static.py │ ├── conftest.py │ ├── test_render_nav_item.py │ ├── test_render_breadcrumb_item.py │ ├── test_render_hidden_errors.py │ ├── test_render_pager.py │ ├── test_render_pagination.py │ ├── test_themes.py │ ├── test_render_form_row.py │ ├── test_render_messages.py │ └── test_render_field.py ├── test_bootstrap5 │ ├── __init__.py │ ├── conftest.py │ ├── test_render_messages.py │ ├── test_render_form_row.py │ ├── test_integrity.py │ ├── test_pagination.py │ ├── test_themes.py │ └── test_render_nav_item.py └── conftest.py ├── requirements ├── style.in ├── build.in ├── docs.in ├── dev.in ├── tests.in ├── style.txt ├── build.txt ├── dev.txt ├── tests.txt └── docs.txt ├── codecov.yml ├── docs ├── changelog.rst ├── examples.rst ├── _static │ ├── css │ │ └── custom.css │ ├── form-example.png │ ├── bootstrap-flask.png │ ├── error-form-example.png │ ├── bootstrap-flask-logo.png │ └── bootstrap-flask-favicon.png ├── _themes │ ├── flask │ │ ├── theme.conf │ │ ├── relations.html │ │ └── layout.html │ ├── flask_small │ │ ├── theme.conf │ │ └── layout.html │ ├── README │ └── LICENSE ├── api.rst ├── Makefile ├── make.bat ├── _templates │ └── sidebarintro.html └── index.rst ├── flask_bootstrap ├── templates │ ├── bootstrap4 │ │ ├── table.html │ │ ├── pagination.html │ │ ├── nav.html │ │ └── utils.html │ ├── bootstrap5 │ │ ├── table.html │ │ ├── pagination.html │ │ ├── nav.html │ │ └── utils.html │ ├── bootstrap │ │ ├── form.html │ │ ├── nav.html │ │ ├── table.html │ │ ├── utils.html │ │ └── pagination.html │ └── base │ │ ├── nav.html │ │ └── utils.html └── static │ ├── bootstrap4 │ └── css │ │ ├── font │ │ └── fonts │ │ │ ├── bootstrap-icons.woff │ │ │ └── bootstrap-icons.woff2 │ │ └── bootswatch │ │ ├── united │ │ ├── _bootswatch.scss │ │ └── _variables.scss │ │ ├── cosmo │ │ ├── _bootswatch.scss │ │ └── _variables.scss │ │ ├── journal │ │ ├── _bootswatch.scss │ │ └── _variables.scss │ │ ├── cerulean │ │ ├── _variables.scss │ │ └── _bootswatch.scss │ │ ├── spacelab │ │ ├── _variables.scss │ │ └── _bootswatch.scss │ │ ├── lumen │ │ └── _variables.scss │ │ ├── pulse │ │ ├── _variables.scss │ │ └── _bootswatch.scss │ │ ├── litera │ │ └── _variables.scss │ │ ├── simplex │ │ ├── _bootswatch.scss │ │ └── _variables.scss │ │ ├── minty │ │ └── _variables.scss │ │ ├── yeti │ │ └── _variables.scss │ │ ├── lux │ │ ├── _variables.scss │ │ └── _bootswatch.scss │ │ └── flatly │ │ └── _variables.scss │ └── bootstrap5 │ └── css │ ├── font │ └── fonts │ │ ├── bootstrap-icons.woff │ │ └── bootstrap-icons.woff2 │ └── bootswatch │ ├── united │ ├── _bootswatch.scss │ └── _variables.scss │ ├── cosmo │ ├── _bootswatch.scss │ └── _variables.scss │ ├── journal │ ├── _bootswatch.scss │ └── _variables.scss │ ├── solar │ └── _bootswatch.scss │ ├── flatly │ └── _bootswatch.scss │ ├── darkly │ └── _bootswatch.scss │ ├── litera │ ├── _bootswatch.scss │ └── _variables.scss │ ├── cerulean │ ├── _variables.scss │ └── _bootswatch.scss │ ├── spacelab │ ├── _variables.scss │ └── _bootswatch.scss │ ├── minty │ ├── _bootswatch.scss │ └── _variables.scss │ ├── pulse │ ├── _variables.scss │ └── _bootswatch.scss │ ├── cyborg │ └── _bootswatch.scss │ ├── simplex │ ├── _bootswatch.scss │ └── _variables.scss │ ├── superhero │ └── _bootswatch.scss │ ├── lumen │ └── _variables.scss │ ├── yeti │ └── _variables.scss │ ├── lux │ └── _variables.scss │ └── materia │ └── _variables.scss ├── examples ├── requirements.txt ├── bootstrap4 │ ├── static │ │ └── favicon.ico │ └── templates │ │ ├── bootswatch.html │ │ ├── flash.html │ │ ├── pagination.html │ │ ├── index.html │ │ ├── nav.html │ │ ├── icon.html │ │ ├── table.html │ │ └── base.html ├── bootstrap5 │ ├── static │ │ └── favicon.ico │ └── templates │ │ ├── bootswatch.html │ │ ├── flash.html │ │ ├── pagination.html │ │ ├── index.html │ │ ├── nav.html │ │ ├── icon.html │ │ ├── table.html │ │ └── base.html ├── list_bootswatch.py ├── README.rst └── update_icons.py ├── .flake8 ├── MANIFEST.in ├── .readthedocs.yml ├── tox.ini ├── .github ├── FUNDING.yml └── workflows │ ├── build.yml │ ├── release.yml │ └── master_bootstrap-flask-example.yml ├── pyproject.toml └── .gitignore /tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /requirements/style.in: -------------------------------------------------------------------------------- 1 | flake8 2 | -------------------------------------------------------------------------------- /tests/test_bootstrap4/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_bootstrap5/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | comment: false 2 | 3 | -------------------------------------------------------------------------------- /requirements/build.in: -------------------------------------------------------------------------------- 1 | wheel 2 | build 3 | -------------------------------------------------------------------------------- /tests/test_bootstrap4/test_render_static.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/changelog.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../CHANGES.rst 2 | -------------------------------------------------------------------------------- /docs/examples.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../examples/README.rst 2 | -------------------------------------------------------------------------------- /docs/_static/css/custom.css: -------------------------------------------------------------------------------- 1 | img.logo { 2 | max-width: 90%; 3 | } 4 | -------------------------------------------------------------------------------- /flask_bootstrap/templates/bootstrap4/table.html: -------------------------------------------------------------------------------- 1 | {% extends 'base/table.html' %} 2 | -------------------------------------------------------------------------------- /flask_bootstrap/templates/bootstrap5/table.html: -------------------------------------------------------------------------------- 1 | {% extends 'base/table.html' %} 2 | -------------------------------------------------------------------------------- /requirements/docs.in: -------------------------------------------------------------------------------- 1 | sphinx 2 | pallets-sphinx-themes 3 | sphinxcontrib-log-cabinet 4 | -------------------------------------------------------------------------------- /examples/requirements.txt: -------------------------------------------------------------------------------- 1 | flask 2 | bootstrap-flask 3 | flask-sqlalchemy 4 | flask-wtf 5 | -------------------------------------------------------------------------------- /requirements/dev.in: -------------------------------------------------------------------------------- 1 | -r tests.in 2 | -r docs.in 3 | -r style.in 4 | pip-compile-multi 5 | tox 6 | -------------------------------------------------------------------------------- /requirements/tests.in: -------------------------------------------------------------------------------- 1 | pytest 2 | pytest-cov 3 | flask-wtf 4 | flask-sqlalchemy 5 | beautifulsoup4 6 | -------------------------------------------------------------------------------- /docs/_static/form-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/helloflask/bootstrap-flask/HEAD/docs/_static/form-example.png -------------------------------------------------------------------------------- /.flake8: -------------------------------------------------------------------------------- 1 | [flake8] 2 | exclude = static,.git,*migrations*,build,.tox,docs 3 | max-line-length = 119 4 | max-complexity = 7 5 | -------------------------------------------------------------------------------- /docs/_static/bootstrap-flask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/helloflask/bootstrap-flask/HEAD/docs/_static/bootstrap-flask.png -------------------------------------------------------------------------------- /docs/_static/error-form-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/helloflask/bootstrap-flask/HEAD/docs/_static/error-form-example.png -------------------------------------------------------------------------------- /docs/_static/bootstrap-flask-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/helloflask/bootstrap-flask/HEAD/docs/_static/bootstrap-flask-logo.png -------------------------------------------------------------------------------- /examples/bootstrap4/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/helloflask/bootstrap-flask/HEAD/examples/bootstrap4/static/favicon.ico -------------------------------------------------------------------------------- /examples/bootstrap5/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/helloflask/bootstrap-flask/HEAD/examples/bootstrap5/static/favicon.ico -------------------------------------------------------------------------------- /docs/_static/bootstrap-flask-favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/helloflask/bootstrap-flask/HEAD/docs/_static/bootstrap-flask-favicon.png -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft flask_bootstrap/static 2 | graft flask_bootstrap/templates 3 | include LICENSE 4 | include README.md 5 | global-exclude *.pyc 6 | global-exclude .DS_Store 7 | -------------------------------------------------------------------------------- /tests/test_bootstrap4/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from flask_bootstrap import Bootstrap4 3 | 4 | 5 | @pytest.fixture(autouse=True) 6 | def bootstrap(app): 7 | yield Bootstrap4(app) 8 | -------------------------------------------------------------------------------- /tests/test_bootstrap5/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from flask_bootstrap import Bootstrap5 3 | 4 | 5 | @pytest.fixture(autouse=True) 6 | def bootstrap(app): 7 | yield Bootstrap5(app) 8 | -------------------------------------------------------------------------------- /flask_bootstrap/static/bootstrap4/css/font/fonts/bootstrap-icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/helloflask/bootstrap-flask/HEAD/flask_bootstrap/static/bootstrap4/css/font/fonts/bootstrap-icons.woff -------------------------------------------------------------------------------- /flask_bootstrap/static/bootstrap4/css/font/fonts/bootstrap-icons.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/helloflask/bootstrap-flask/HEAD/flask_bootstrap/static/bootstrap4/css/font/fonts/bootstrap-icons.woff2 -------------------------------------------------------------------------------- /flask_bootstrap/static/bootstrap5/css/font/fonts/bootstrap-icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/helloflask/bootstrap-flask/HEAD/flask_bootstrap/static/bootstrap5/css/font/fonts/bootstrap-icons.woff -------------------------------------------------------------------------------- /flask_bootstrap/static/bootstrap5/css/font/fonts/bootstrap-icons.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/helloflask/bootstrap-flask/HEAD/flask_bootstrap/static/bootstrap5/css/font/fonts/bootstrap-icons.woff2 -------------------------------------------------------------------------------- /.readthedocs.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | python: 3 | install: 4 | - requirements: requirements/docs.txt 5 | - method: pip 6 | path: . 7 | sphinx: 8 | builder: dirhtml 9 | fail_on_warning: true 10 | -------------------------------------------------------------------------------- /examples/bootstrap4/templates/bootswatch.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | {% from 'bootstrap4/form.html' import render_form %} 3 | 4 | {% block content %} 5 |

Bootswatch

6 | {{ render_form(form) }} 7 | {% endblock %} 8 | -------------------------------------------------------------------------------- /examples/bootstrap5/templates/bootswatch.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | {% from 'bootstrap5/form.html' import render_form %} 3 | 4 | {% block content %} 5 |

Bootswatch

6 | {{ render_form(form) }} 7 | {% endblock %} 8 | -------------------------------------------------------------------------------- /docs/_themes/flask/theme.conf: -------------------------------------------------------------------------------- 1 | [theme] 2 | inherit = basic 3 | stylesheet = flasky.css 4 | pygments_style = flask_theme_support.FlaskyStyle 5 | 6 | [options] 7 | index_logo = '' 8 | index_logo_height = 120px 9 | touch_icon = 10 | -------------------------------------------------------------------------------- /docs/_themes/flask_small/theme.conf: -------------------------------------------------------------------------------- 1 | [theme] 2 | inherit = basic 3 | stylesheet = flasky.css 4 | nosidebar = true 5 | pygments_style = flask_theme_support.FlaskyStyle 6 | 7 | [options] 8 | index_logo = '' 9 | index_logo_height = 120px 10 | github_fork = '' 11 | -------------------------------------------------------------------------------- /examples/bootstrap4/templates/flash.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block content %} 4 | The messages above were rendered with the following code: 5 |
{% raw %}{{ render_messages(container=False, dismissible=True) }}{% endraw %}
6 | {% endblock %} 7 | -------------------------------------------------------------------------------- /examples/bootstrap5/templates/flash.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block content %} 4 | The messages above were rendered with the following code: 5 |
{% raw %}{{ render_messages(container=False, dismissible=True) }}{% endraw %}
6 | {% endblock %} 7 | -------------------------------------------------------------------------------- /flask_bootstrap/templates/bootstrap5/pagination.html: -------------------------------------------------------------------------------- 1 | {% extends 'base/pagination.html' %} 2 | 3 | {% macro get_current_page(page) %} 4 |
  • 5 | {{ page }} 6 |
  • 7 | {% endmacro %} 8 | -------------------------------------------------------------------------------- /flask_bootstrap/templates/bootstrap4/pagination.html: -------------------------------------------------------------------------------- 1 | {% extends 'base/pagination.html' %} 2 | 3 | {% macro get_current_page(page) %} 4 |
  • 5 | {{ page }} (current) 6 |
  • 7 | {% endmacro %} 8 | -------------------------------------------------------------------------------- /flask_bootstrap/templates/bootstrap/form.html: -------------------------------------------------------------------------------- 1 | {{ warn('For Bootstrap 4, please import macros from "bootstrap4/" path (e.g. "from \'bootstrap4/form.html\' import render_form"), the "bootstrap/" path is deprecated and will be removed in version 3.0.', stacklevel=2) }} 2 | {% extends 'bootstrap4/form.html' %} 3 | -------------------------------------------------------------------------------- /flask_bootstrap/templates/bootstrap/nav.html: -------------------------------------------------------------------------------- 1 | {{ warn('For Bootstrap 4, please import macros from "bootstrap4/" path (e.g. "from \'bootstrap4/nav.html\' import render_nav_item"), the "bootstrap/" path is deprecated and will be removed in version 3.0.', stacklevel=2) }} 2 | {% extends 'bootstrap4/nav.html' %} 3 | -------------------------------------------------------------------------------- /flask_bootstrap/templates/bootstrap/table.html: -------------------------------------------------------------------------------- 1 | {{ warn('For Bootstrap 4, please import macros from "bootstrap4/" path (e.g. "from \'bootstrap4/table.html\' import render_table"), the "bootstrap/" path is deprecated and will be removed in version 3.0.', stacklevel=2) }} 2 | {% extends 'bootstrap4/table.html' %} 3 | -------------------------------------------------------------------------------- /flask_bootstrap/templates/bootstrap/utils.html: -------------------------------------------------------------------------------- 1 | {{ warn('For Bootstrap 4, please import macros from "bootstrap4/" path (e.g. "from \'bootstrap4/utils.html\' import render_icon"), the "bootstrap/" path is deprecated and will be removed in version 3.0.', stacklevel=2) }} 2 | {% extends 'bootstrap4/utils.html' %} 3 | -------------------------------------------------------------------------------- /flask_bootstrap/templates/bootstrap/pagination.html: -------------------------------------------------------------------------------- 1 | {{ warn('For Bootstrap 4, please import macros from "bootstrap4/" path (e.g. "from \'bootstrap4/pagination.html\' import render_pager"), the "bootstrap/" path is deprecated and will be removed in version 3.0.', stacklevel=2) }} 2 | {% extends 'bootstrap4/pagination.html' %} 3 | -------------------------------------------------------------------------------- /flask_bootstrap/static/bootstrap4/css/bootswatch/united/_bootswatch.scss: -------------------------------------------------------------------------------- 1 | // United 4.6.1 2 | // Bootswatch 3 | 4 | 5 | // Variables =================================================================== 6 | 7 | $web-font-path: "https://fonts.googleapis.com/css2?family=Ubuntu:wght@400;700&display=swap" !default; 8 | @if $web-font-path { 9 | @import url($web-font-path); 10 | } 11 | -------------------------------------------------------------------------------- /requirements/style.txt: -------------------------------------------------------------------------------- 1 | # SHA1:8f27e4f0b0e1fabc56425bc40b6e79fabb64c9af 2 | # 3 | # This file is autogenerated by pip-compile-multi 4 | # To update, run: 5 | # 6 | # pip-compile-multi 7 | # 8 | flake8==7.1.2 9 | # via -r requirements/style.in 10 | mccabe==0.7.0 11 | # via flake8 12 | pycodestyle==2.12.1 13 | # via flake8 14 | pyflakes==3.2.0 15 | # via flake8 16 | -------------------------------------------------------------------------------- /docs/api.rst: -------------------------------------------------------------------------------- 1 | API Reference 2 | ============== 3 | 4 | .. module:: flask_bootstrap 5 | 6 | .. autoclass:: _Bootstrap 7 | :members: 8 | :undoc-members: 9 | 10 | 11 | .. autoclass:: Bootstrap4 12 | :members: 13 | :undoc-members: 14 | 15 | 16 | .. autoclass:: Bootstrap5 17 | :members: 18 | :undoc-members: 19 | 20 | 21 | .. autoclass:: SwitchField 22 | :members: 23 | :undoc-members: 24 | -------------------------------------------------------------------------------- /flask_bootstrap/templates/base/nav.html: -------------------------------------------------------------------------------- 1 | {% macro render_breadcrumb_item(endpoint, text) %} 2 | {% set active = True if request.endpoint and request.endpoint == endpoint else False %} 3 | 10 | {% endmacro %} 11 | -------------------------------------------------------------------------------- /requirements/build.txt: -------------------------------------------------------------------------------- 1 | # SHA1:574f214f412321e33a09f6d788b9561e2281c879 2 | # 3 | # This file is autogenerated by pip-compile-multi 4 | # To update, run: 5 | # 6 | # pip-compile-multi 7 | # 8 | build==1.2.2.post1 9 | # via -r requirements/build.in 10 | importlib-metadata==8.5.0 11 | # via build 12 | packaging==24.2 13 | # via build 14 | pyproject-hooks==1.2.0 15 | # via build 16 | tomli==2.2.1 17 | # via build 18 | wheel==0.45.1 19 | # via -r requirements/build.in 20 | zipp==3.20.2 21 | # via importlib-metadata 22 | -------------------------------------------------------------------------------- /flask_bootstrap/static/bootstrap5/css/bootswatch/united/_bootswatch.scss: -------------------------------------------------------------------------------- 1 | // United 5.3.5 2 | // Bootswatch 3 | 4 | 5 | // Variables 6 | 7 | $web-font-path: "https://fonts.googleapis.com/css2?family=Ubuntu:wght@400;700&display=swap" !default; 8 | @if $web-font-path { 9 | @import url("#{$web-font-path}"); 10 | } 11 | 12 | // Indicators 13 | 14 | .badge { 15 | &.bg-light { 16 | color: $body-color; 17 | } 18 | } 19 | 20 | // Tables 21 | 22 | .table-primary, 23 | .table-secondary, 24 | .table-success, 25 | .table-warning, 26 | .table-danger, 27 | .table-info, 28 | .table-light { 29 | --#{$prefix}table-color: #{$body-color}; 30 | } 31 | -------------------------------------------------------------------------------- /tests/test_bootstrap5/test_render_messages.py: -------------------------------------------------------------------------------- 1 | from flask import flash, render_template_string 2 | 3 | 4 | def test_render_messages(app, client): 5 | @app.route('/messages') 6 | def test_messages(): 7 | flash('test message', 'danger') 8 | return render_template_string(''' 9 | {% from 'bootstrap5/utils.html' import render_messages %} 10 | {{ render_messages(dismissible=True) }} 11 | ''') 12 | 13 | response = client.get('/messages') 14 | data = response.get_data(as_text=True) 15 | assert 'class="btn-close" data-bs-dismiss="alert" aria-label="Close">' in data 16 | -------------------------------------------------------------------------------- /examples/bootstrap4/templates/pagination.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | {% from 'bootstrap4/pagination.html' import render_pager, render_pagination %} 3 | 4 | {% block content %} 5 |

    Messages

    6 | {% for message in messages %} 7 | Message: {{ message.id }}
    8 | {% endfor %} 9 | 10 |

    Render a simple pagination component with render_pager

    11 |
    {% raw %}{{ render_pager(pagination) }}{% endraw %}
    12 | {{ render_pager(pagination) }} 13 | 14 |

    Render a standard pagination component with render_pagination

    15 |
    {% raw %}{{ render_pagination(pagination) }}{% endraw %}
    16 | {{ render_pagination(pagination) }} 17 | {% endblock %} 18 | -------------------------------------------------------------------------------- /examples/bootstrap5/templates/pagination.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | {% from 'bootstrap5/pagination.html' import render_pager, render_pagination %} 3 | 4 | {% block content %} 5 |

    Messages

    6 | {% for message in messages %} 7 | Message: {{ message.id }}
    8 | {% endfor %} 9 | 10 |

    Render a simple pagination component with render_pager

    11 |
    {% raw %}{{ render_pager(pagination) }}{% endraw %}
    12 | {{ render_pager(pagination) }} 13 | 14 |

    Render a standard pagination component with render_pagination

    15 |
    {% raw %}{{ render_pagination(pagination) }}{% endraw %}
    16 | {{ render_pagination(pagination) }} 17 | {% endblock %} 18 | -------------------------------------------------------------------------------- /flask_bootstrap/templates/bootstrap4/nav.html: -------------------------------------------------------------------------------- 1 | {% extends 'base/nav.html' %} 2 | 3 | {% macro render_nav_item(endpoint, text, _badge='', _use_li=False, _badge_classes='badge badge-light') %} 4 | {% set active = True if request.endpoint and request.endpoint == endpoint else False %} 5 | {% if _use_li %}{% endif %} 11 | {% endmacro %} 12 | -------------------------------------------------------------------------------- /flask_bootstrap/templates/bootstrap5/nav.html: -------------------------------------------------------------------------------- 1 | {% extends 'base/nav.html' %} 2 | 3 | {% macro render_nav_item(endpoint, text, _badge='', _use_li=False, _badge_classes='badge text-bg-light') %} 4 | {% set active = True if request.endpoint and request.endpoint == endpoint else False %} 5 | {% if _use_li %}{% endif %} 11 | {% endmacro %} 12 | -------------------------------------------------------------------------------- /tests/test_bootstrap5/test_render_form_row.py: -------------------------------------------------------------------------------- 1 | from flask import render_template_string 2 | 3 | 4 | def test_render_form_row(app, client, hello_form): 5 | @app.route('/form') 6 | def test(): 7 | form = hello_form() 8 | return render_template_string(''' 9 | {% from 'bootstrap5/form.html' import render_form_row %} 10 | {{ render_form_row([form.username, form.password]) }} 11 | ''', form=form) 12 | response = client.get('/form') 13 | data = response.get_data(as_text=True) 14 | assert '
    ' not in data 15 | assert '
    ' in data 16 | assert '
    ' in data 17 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | SPHINXPROJ = Bootstrap-Flask 8 | SOURCEDIR = . 9 | BUILDDIR = _build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -------------------------------------------------------------------------------- /docs/_themes/flask/relations.html: -------------------------------------------------------------------------------- 1 |

    Related Topics

    2 | 20 | -------------------------------------------------------------------------------- /examples/bootstrap4/templates/index.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block content %} 4 |

    Bootstrap-Flask Demo Application

    5 |

    This demo uses Bootstrap version 4.

    6 | 16 | {% endblock %} 17 | -------------------------------------------------------------------------------- /examples/bootstrap5/templates/index.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block content %} 4 |

    Bootstrap-Flask Demo Application

    5 |

    This demo uses Bootstrap version 5.

    6 | 16 | {% endblock %} 17 | -------------------------------------------------------------------------------- /flask_bootstrap/static/bootstrap4/css/bootswatch/cosmo/_bootswatch.scss: -------------------------------------------------------------------------------- 1 | // Cosmo 4.6.1 2 | // Bootswatch 3 | 4 | 5 | // Variables =================================================================== 6 | 7 | $web-font-path: "https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@300;400;700&display=swap" !default; 8 | @if $web-font-path { 9 | @import url($web-font-path); 10 | } 11 | 12 | // Typography ================================================================== 13 | 14 | body { 15 | -webkit-font-smoothing: antialiased; 16 | } 17 | 18 | // Progress bars =============================================================== 19 | 20 | .progress { 21 | @include box-shadow(none); 22 | 23 | .progress-bar { 24 | font-size: 8px; 25 | line-height: 8px; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | isolated_build = True 3 | envlist = py39, py310, py311, py312, py313, flake8, docs 4 | skip_missing_interpreters = true 5 | 6 | [gh-actions] 7 | python = 8 | 3.9: py39 9 | 3.10: py310 10 | 3.11: py311 11 | 3.12: py312 12 | 3.13: py313 13 | 14 | [testenv] 15 | deps = 16 | -r requirements/tests.txt 17 | commands = 18 | pytest 19 | 20 | [testenv:flake8] 21 | deps = 22 | -r requirements/style.txt 23 | commands = 24 | flake8 flask_bootstrap tests 25 | 26 | [testenv:covarage] 27 | deps = 28 | -r requirements/tests.txt 29 | commands = 30 | pytest --cov=flask_bootstrap --cov-branch 31 | 32 | [testenv:docs] 33 | deps = 34 | -r requirements/docs.txt 35 | commands = 36 | sphinx-build -W -b html -d {envtmpdir}/doctrees docs {envtmpdir}/html 37 | -------------------------------------------------------------------------------- /docs/_themes/flask_small/layout.html: -------------------------------------------------------------------------------- 1 | {% extends "basic/layout.html" %} 2 | {% block header %} 3 | {{ super() }} 4 | {% if pagename == 'index' %} 5 |
    6 | {% endif %} 7 | {% endblock %} 8 | {% block footer %} 9 | {% if pagename == 'index' %} 10 |
    11 | {% endif %} 12 | {% endblock %} 13 | {# do not display relbars #} 14 | {% block relbar1 %}{% endblock %} 15 | {% block relbar2 %} 16 | {% if theme_github_fork %} 17 | Fork me on GitHub 19 | {% endif %} 20 | {% endblock %} 21 | {% block sidebar1 %}{% endblock %} 22 | {% block sidebar2 %}{% endblock %} 23 | -------------------------------------------------------------------------------- /docs/_themes/flask/layout.html: -------------------------------------------------------------------------------- 1 | {%- extends "basic/layout.html" %} 2 | {%- block extrahead %} 3 | {{ super() }} 4 | {% if theme_touch_icon %} 5 | 6 | {% endif %} 7 | 8 | {% endblock %} 9 | {%- block relbar2 %}{% endblock %} 10 | {% block header %} 11 | {{ super() }} 12 | {% if pagename == 'index' %} 13 |
    14 | {% endif %} 15 | {% endblock %} 16 | {%- block footer %} 17 | 21 | {% if pagename == 'index' %} 22 |
    23 | {% endif %} 24 | {%- endblock %} 25 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: bootstrap-flask 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 14 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=. 11 | set BUILDDIR=_build 12 | set SPHINXPROJ=Bootstrap-Flask 13 | 14 | if "%1" == "" goto help 15 | 16 | %SPHINXBUILD% >NUL 2>NUL 17 | if errorlevel 9009 ( 18 | echo. 19 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 20 | echo.installed, then set the SPHINXBUILD environment variable to point 21 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 22 | echo.may add the Sphinx directory to PATH. 23 | echo. 24 | echo.If you don't have Sphinx installed, grab it from 25 | echo.http://sphinx-doc.org/ 26 | exit /b 1 27 | ) 28 | 29 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 30 | goto end 31 | 32 | :help 33 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 34 | 35 | :end 36 | popd 37 | -------------------------------------------------------------------------------- /examples/list_bootswatch.py: -------------------------------------------------------------------------------- 1 | """List Bootstrap themes RadioField.""" 2 | 3 | from os import listdir 4 | 5 | # pylint:disable=unspecified-encoding 6 | 7 | 8 | def list_names(version): 9 | """List template file names.""" 10 | print(f"To add to bootstrap{version}/app.py") 11 | print(" theme_name = RadioField(") 12 | print(" default='default',") 13 | print(" choices=[") 14 | print(" ('default', 'none'),") 15 | base = f'../flask_bootstrap/static/bootstrap{version}/css/bootswatch' 16 | name = '' 17 | for directory in sorted(listdir(base)): 18 | with open(f'{base}/{directory}/_bootswatch.scss') as scss: 19 | for line in scss: 20 | name = line.strip()[3:] 21 | break 22 | print(f" ('{directory}', '{name}'),") 23 | print(" ]") 24 | print(" )") 25 | 26 | 27 | for value in (4, 5): 28 | list_names(value) 29 | -------------------------------------------------------------------------------- /tests/test_bootstrap4/test_render_nav_item.py: -------------------------------------------------------------------------------- 1 | from flask import render_template_string 2 | 3 | 4 | def test_render_nav_item_active(app, client): 5 | @app.route('/active') 6 | def item_foo(): 7 | return render_template_string(''' 8 | {% from 'bootstrap4/nav.html' import render_nav_item %} 9 | {{ render_nav_item('item_foo', 'Foo') }} 10 | ''') 11 | 12 | @app.route('/not_active') 13 | def item_bar(): 14 | return render_template_string(''' 15 | {% from 'bootstrap4/nav.html' import render_nav_item %} 16 | {{ render_nav_item('item_foo', 'Foo') }} 17 | ''') 18 | 19 | response = client.get('/active') 20 | data = response.get_data(as_text=True) 21 | assert '' in data 22 | 23 | response = client.get('/active_item') 24 | data = response.get_data(as_text=True) 25 | assert '