Download
To set up the Metronic Tailwind CSS integration in Flask, you can download the Metronic Integration Examples from our
GitHub repository
. These examples provide a quick way to integrate the Metronic styles into your Flask project. This will give you a working starting point that you can customize to fit your needs.
Please note that the sample project does not include the Metronic Tailwind CSS source files by default. To integrate the styles, you need to copy the Metronic Tailwind CSS source files from your downloaded Metronic folder.
1
Clone Integration Repository
Clone the Metronic integration repository to get the Flask example:
git clone https://github.com/keenthemes/metronic-tailwind-html-integration.git
cd metronic-tailwind-html-integration/metronic-tailwind-flask
2
Copy Assets Folder
Copy the
assets
folder from the
metronic-tailwind-html/dist
directory into your Flask project root. The resulting directory structure should look like this:
assets/
.
3
Automated Setup (Recommended)
Use the automated setup scripts to quickly configure your environment and dependencies:
# macOS/Linux
./setup.sh
# Windows
setup.bat
The setup script will create a virtual environment, install dependencies, and configure your environment automatically.
4
Start Development Server
Use the automated start scripts to launch your Flask application:
# Using start scripts (recommended)
./start.sh # macOS/Linux
start.bat # Windows
# Or manually
python3 run.py
Open your browser and navigate to
http://127.0.0.1:5000
to see your Flask app in action. You can explore both demo layouts:
# Demo 1 - Sidebar Layout
http://127.0.0.1:5000/demo1/
# Demo 2 - Header Layout
http://127.0.0.1:5000/demo2/
If you prefer to create a project from scratch, follow these manual steps.
Creating a Flask Project
This guide will walk you through the step-by-step process of creating a Flask project from scratch.
1
Install Python
Before creating a Flask project, you need to have Python installed. You can download Python from
https://www.python.org/downloads/
.
We recommend Python 3.8 or higher.
2
Use Integration Template (Recommended)
The fastest way to get started is to use the pre-built Flask integration template that includes automated setup scripts:
git clone https://github.com/keenthemes/metronic-tailwind-html-integration.git
cd metronic-tailwind-html-integration/metronic-tailwind-flask
This template includes setup scripts, project structure, blueprints, and demo layouts ready to use.
3
Manual Project Setup (Alternative)
If you prefer to create a project from scratch, follow these manual steps:
# Create project directory
mkdir metronic-flask
cd metronic-flask
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install Flask
pip install Flask
# Create basic structure
mkdir -p app/demo1 app/demo2 templates/demo1 templates/demo2 templates/partials
4
Create Application Factory
Create a Flask application using the application factory pattern. Create
app/__init__.py
:
from flask import Flask, redirect, url_for
def create_app():
app = Flask(__name__, static_folder='../assets', static_url_path='/assets')
# Register blueprints
from app.demo1 import bp as demo1_bp
from app.demo2 import bp as demo2_bp
app.register_blueprint(demo1_bp, url_prefix='/demo1')
app.register_blueprint(demo2_bp, url_prefix='/demo2')
@app.route('/')
def index():
return redirect(url_for('demo1.index'))
return app
5
Create Application Entry Point
Create
run.py
as your application entry point:
from app import create_app
app = create_app()
if __name__ == '__main__':
app.run(debug=True, host='127.0.0.1', port=5000)
6
Test Your Setup
Run your Flask application to verify the setup:
python run.py
Open your browser and navigate to
http://127.0.0.1:5000
to see your Flask app in action.
Integrate Metronic Core with Flask
This guide will walk you through integrating Metronic core functionality into your Flask project, including template structure, blueprints, and routing.
1
Understanding the Flask Integration Structure
The Flask integration uses a modern application structure with blueprints, organized as follows:
metronic-tailwind-flask/
├── app/ # Main application package
│ ├── __init__.py # Application factory
│ ├── config.py # Configuration management
│ ├── models.py # Mock data models
│ ├── demo1/ # Demo 1 blueprint (sidebar)
│ └── demo2/ # Demo 2 blueprint (header)
├── templates/ # Jinja2 templates
│ ├── demo1/ # Demo 1 pages
│ ├── demo2/ # Demo 2 pages
│ └── partials/ # Reusable components
├── assets/ # Metronic assets (CSS, JS, media)
├── tests/ # Test suite
├── setup.sh / setup.bat # Automated setup scripts
├── start.sh / start.bat # Development startup scripts
└── run.py # Application entry point
2
Application Factory Pattern
The Flask integration uses the application factory pattern in
app/__init__.py
:
from flask import Flask, redirect, url_for
def create_app():
app = Flask(__name__, static_folder='../assets', static_url_path='/assets')
# Configuration
app.config.from_object('app.config.Config')
# Register blueprints
from app.demo1 import bp as demo1_bp
from app.demo2 import bp as demo2_bp
from app.main import bp as main_bp
app.register_blueprint(main_bp)
app.register_blueprint(demo1_bp, url_prefix='/demo1')
app.register_blueprint(demo2_bp, url_prefix='/demo2')
return app
3
Blueprint Organization
The integration includes three main blueprints. Demo1 blueprint (
app/demo1/__init__.py
) for sidebar layout:
from flask import Blueprint, render_template
from app.models import get_dashboard_context
bp = Blueprint('demo1', __name__)
@bp.route('/')
def index():
context = get_dashboard_context()
return render_template('demo1/index.html', **context)
@bp.route('/dashboard')
def dashboard():
context = get_dashboard_context()
return render_template('demo1/index.html', **context)
Demo2 blueprint (
app/demo2/__init__.py
) for header layout:
from flask import Blueprint, render_template
from app.models import get_analytics_context
bp = Blueprint('demo2', __name__)
@bp.route('/')
def index():
context = get_analytics_context()
return render_template('demo2/index.html', **context)
@bp.route('/analytics')
def analytics():
context = get_analytics_context()
return render_template('demo2/index.html', **context)
4
Configuration Management
The integration includes a configuration system in
app/config.py
:
import os
from pathlib import Path
class Config:
"""Base configuration class."""
# Flask settings
SECRET_KEY = os.environ.get('SECRET_KEY') or 'dev-secret-key-change-in-production'
# Application settings
APP_NAME = 'Metronic Flask Integration'
APP_VERSION = '1.0.0'
# Static files
STATIC_FOLDER = Path(__file__).parent.parent / 'assets'
STATIC_URL_PATH = '/assets'
# Template settings
TEMPLATES_AUTO_RELOAD = True
5
Create Base Templates
Create base templates for template inheritance. First, create
templates/demo1/base.html
:
<!DOCTYPE html>
<html lang="en">
<head>
{% include 'partials/head.html' %}
<title>
{% block title %}Metronic Flask{% endblock %}
</title>
</head>
<body>
<div class="d-flex flex-column flex-root">
<div class="page d-flex flex-row flex-column-fluid">
{% include 'demo1/partials/sidebar.html' %}
<div class="wrapper d-flex flex-column flex-row-fluid">
{% include 'demo1/partials/header.html' %}
<div class="content d-flex flex-column flex-column-fluid">
{% block content %}{% endblock %}
</div>
</div>
</div>
</div>
{% include 'partials/scripts.html' %}
</body>
</html>
6
Create Template Partials
Create reusable template partials. Start with
templates/partials/head.html
:
<meta charset="utf-8"/>
<meta content="width=device-width, initial-scale=1" name="viewport"/>
<link href="{{ url_for('static', filename='media/logos/favicon.ico') }}" rel="shortcut icon"/>
<link href="{{ url_for('static', filename='css/style.bundle.css') }}" rel="stylesheet"/>
6
Mock Data Models
The integration includes a comprehensive mock data system in
app/models.py
:
def get_dashboard_context():
"""Get context data for Demo 1 (sidebar layout)."""
return {
'user': User("Max Smith", "max@keenthemes.com", "/assets/media/avatars/300-1.jpg"),
'stats': {
'total_users': 15000,
'revenue': 75000,
'orders': 450,
'growth': 15.2
},
'recent_activities': get_recent_activities(),
'chart_data': get_chart_data()
}
def get_analytics_context():
"""Get context data for Demo 2 (header layout)."""
return {
'user': User("Sean Bean", "sean@keenthemes.com", "/assets/media/avatars/300-5.jpg"),
'analytics': {
'visitors': 24500,
'bounce_rate': 35.8,
'page_views': 125000,
'conversion': 8.2
},
'traffic_sources': get_traffic_sources(),
'performance_data': get_performance_data()
}
7
Testing Integration
The integration includes a comprehensive test suite. Run tests to verify your setup:
# Run all tests
pytest
# Run with coverage report
pytest --cov=app
# Run specific test modules
pytest tests/test_demo1.py -v
pytest tests/test_demo2.py -v
# Run tests with detailed output
pytest tests/ -v --tb=short
The test suite covers route functionality, template rendering, asset loading, and configuration validation.
Integrate Metronic & KtUI with Flask
This guide will walk you through integrating Metronic and KtUI styles into your Flask project. The Flask integration uses pre-built CSS and JS files for simplicity.
1
Copy Metronic Assets
Copy the complete
assets
folder from your Metronic HTML package's
dist
directory to your Flask project root:
cp -r /path/to/metronic-tailwind-html/dist/assets ./assets
2
Configure Static Files
Update your Flask app configuration to serve static files from the assets directory:
app = Flask(__name__, static_folder='assets', static_url_path='/assets')
3
Create Head Partial
Create
templates/partials/head.html
to include Metronic stylesheets:
<meta charset="utf-8"/>
<meta content="Metronic Flask Integration" name="description"/>
<meta content="flask, metronic, tailwind, dashboard" name="keywords"/>
<meta content="width=device-width, initial-scale=1" name="viewport"/>
<meta content="en_US" property="og:locale"/>
<meta content="article" property="og:type"/>
<meta content="Metronic Flask" property="og:title"/>
<meta content="Metronic by Keenthemes" property="og:site_name"/>
<link href="{{ url_for('static', filename='media/logos/favicon.ico') }}" rel="shortcut icon"/>
<!--begin::Fonts(mandatory for all pages)-->
<link href="https://fonts.googleapis.com/css?family=Inter:300,400,500,600,700" rel="stylesheet"/>
<!--end::Fonts-->
<!--begin::Vendor Stylesheets(used for this page only)-->
<link href="{{ url_for('static', filename='plugins/custom/datatables/datatables.bundle.css') }}" rel="stylesheet" type="text/css"/>
<!--end::Vendor Stylesheets-->
<!--begin::Global Stylesheets Bundle(mandatory for all pages)-->
<link href="{{ url_for('static', filename='css/style.bundle.css') }}" rel="stylesheet" type="text/css"/>
4
Create Scripts Partial
Create
templates/partials/scripts.html
to include Metronic JavaScript:
<!--begin::Javascript-->
<script>
var hostUrl = "{{ url_for('static', filename='') }}";
</script>
<!--begin::Global Javascript Bundle(mandatory for all pages)-->
<script src="{{ url_for('static', filename='plugins/global/plugins.bundle.js') }}">
</script>
<script src="{{ url_for('static', filename='js/scripts.bundle.js') }}">
</script>
<!--end::Global Javascript Bundle-->
<!--begin::Vendors Javascript(used for this page only)-->
<script src="{{ url_for('static', filename='plugins/custom/datatables/datatables.bundle.js') }}">
</script>
<!--end::Vendors Javascript-->
<!--begin::Custom Javascript(optional)-->
<script src="{{ url_for('static', filename='js/custom/apps/user-management/users/list/table.js') }}">
</script>
<script src="{{ url_for('static', filename='js/custom/apps/user-management/users/list/export-users.js') }}">
</script>
<script src="{{ url_for('static', filename='js/custom/apps/user-management/users/list/add-user.js') }}">
</script>
<script src="{{ url_for('static', filename='js/widgets.bundle.js') }}">
</script>
<script src="{{ url_for('static', filename='js/custom/widgets.js') }}">
</script>
<script src="{{ url_for('static', filename='js/custom/apps/chat/chat.js') }}">
</script>
<script src="{{ url_for('static', filename='js/custom/utilities/modals/upgrade-plan.js') }}">
</script>
<script src="{{ url_for('static', filename='js/custom/utilities/modals/create-app.js') }}">
</script>
<script src="{{ url_for('static', filename='js/custom/utilities/modals/users-search.js') }}">
</script>
<!--end::Custom Javascript-->
<!--end::Javascript-->
5
Create Demo Templates
Convert your Metronic HTML templates to Jinja2. Create
templates/demo1/index.html
:
{% extends "demo1/base.html" %}
{% block title %}Dashboard - Metronic Flask{% endblock %}
{% block content %}
<div class="app-toolbar py-3 py-lg-6" id="kt_app_toolbar">
<div class="app-container container-xxl d-flex flex-stack" id="kt_app_toolbar_container">
<div class="page-title d-flex flex-column justify-content-center flex-wrap me-3">
<h1 class="page-heading d-flex text-dark fw-bold fs-3 flex-column justify-content-center my-0">
Dashboard
</h1>
<ul class="breadcrumb breadcrumb-separatorless fw-semibold fs-7 my-0 pt-1">
<li class="breadcrumb-item text-muted">
<a class="text-muted text-hover-primary" href="{{ url_for('demo1.index') }}">
Home
</a>
</li>
<li class="breadcrumb-item">
<span class="bullet bg-gray-400 w-5px h-2px">
</span>
</li>
<li class="breadcrumb-item text-muted">
Dashboard
</li>
</ul>
</div>
</div>
</div>
<div class="app-content flex-column-fluid" id="kt_app_content">
<div class="app-container container-xxl" id="kt_app_content_container">
<!-- Dashboard content goes here -->
<div class="row g-5 g-xl-10 mb-5 mb-xl-10">
<div class="col-md-6 col-lg-6 col-xl-6 col-xxl-3 mb-md-5 mb-xl-10">
<div class="card card-flush bgi-no-repeat bgi-size-contain bgi-position-x-end h-md-50 mb-5 mb-xl-10">
<div class="card-header pt-5">
<div class="card-title d-flex flex-column">
<span class="fs-2hx fw-bold text-dark me-2 lh-1 ls-n2">
{{ stats.total_users }}
</span>
<span class="text-gray-400 pt-1 fw-semibold fs-6">
Total Users
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
6
Update Routes with Context
Update your blueprint routes to pass data to templates:
from flask import Blueprint, render_template
from models import get_dashboard_stats, get_user_data
demo1_bp = Blueprint('demo1', __name__)
@demo1_bp.route('/')
def index():
stats = get_dashboard_stats()
user = get_user_data()
return render_template('demo1/index.html', stats=stats, user=user)
7
Development Workflow
The integration includes automated scripts for development workflow:
# Daily development startup
./start.sh # macOS/Linux
start.bat # Windows
# Manual startup
python3 run.py
# Run with specific host/port
python3 run.py --host=0.0.0.0 --port=8000
Visit your application URLs to explore both demo layouts:
# Demo 1 - Sidebar Layout (Dashboard)
http://127.0.0.1:5000/demo1/
# Demo 2 - Header Layout (Analytics)
http://127.0.0.1:5000/demo2/
# Main redirect (goes to Demo 1)
http://127.0.0.1:5000/
8
Customization & Next Steps
Now that your integration is working, you can customize it for your needs:
# Add new routes to blueprints
# Edit app/demo1/__init__.py or app/demo2/__init__.py
# Customize templates
# Modify files in templates/demo1/ or templates/demo2/
# Update mock data
# Edit app/models.py to add your data sources
# Add database integration
# Install SQLAlchemy: pip install Flask-SQLAlchemy
# Run tests to verify changes
pytest tests/ -v