Flask-Wiki

March 26, 2026 ยท View on GitHub

A lightweight, file-based wiki system built as a Flask extension. Create, edit, search, and manage wiki pages stored as Markdown files on the filesystem -- no database required.

Features

  • Markdown pages with metadata (title, tags)
  • Full-text search powered by Whoosh
  • File/image uploads
  • WikiLinks ([[Page Name]] syntax)
  • Multilingual support
  • Rich editor with live preview (EasyMDE)
  • Customizable templates and permissions

Installation

pip install flask-wiki

Quick start

from flask import Flask
from flask_wiki import Wiki

app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key'
Wiki(app)

Or using the application factory pattern:

from flask import Flask
from flask_wiki import Wiki

wiki = Wiki()

def create_app():
    app = Flask(__name__)
    app.config['SECRET_KEY'] = 'your-secret-key'
    wiki.init_app(app)
    return app

The wiki will be available at /help by default (configurable via WIKI_URL_PREFIX).

Initialize the search index

Before using search, initialize the Whoosh index:

flask flask_wiki init-index
flask flask_wiki index

How it works

Wiki pages are plain Markdown files stored in a content directory (./data by default). The URL structure mirrors the filesystem: /help/guides/setup maps to data/guides/setup.md.

Each page file has an optional metadata header followed by the Markdown body:

title: My Page Title
tags: setup, guide

# Content starts here

Regular markdown content...

The wiki registers a Flask Blueprint with routes for viewing, editing, searching, and managing pages. Uploaded files (images) are stored in a subfolder and served via middleware.

Permissions

Flask-Wiki uses a callable-based permission system. The host application provides functions that return True or False to control access. By default, everything is open (all lambdas return True).

There are four permission settings:

SettingPurpose
WIKI_READ_VIEW_PERMISSIONControls access to read routes (view pages, search). Returns 403 if False.
WIKI_EDIT_VIEW_PERMISSIONControls access to edit routes (edit, delete, upload). Returns 403 if False.
WIKI_READ_UI_PERMISSIONControls visibility of read-related UI elements in templates.
WIKI_EDIT_UI_PERMISSIONControls visibility of edit buttons/links in templates.

Each permission is a callable (no arguments) that is evaluated per-request. This lets you integrate with any authentication system -- Flask-Login, session-based auth, API tokens, etc.

Example: integrating with Flask-Login

from flask_login import current_user

app.config['WIKI_READ_VIEW_PERMISSION'] = lambda: current_user.is_authenticated
app.config['WIKI_EDIT_VIEW_PERMISSION'] = lambda: current_user.is_authenticated and current_user.has_role('editor')
app.config['WIKI_EDIT_UI_PERMISSION'] = app.config['WIKI_EDIT_VIEW_PERMISSION']

The VIEW permissions are enforced server-side via route decorators. The UI permissions only toggle visibility of buttons and links in the templates -- they do not enforce access control on their own. Typically you'll set the UI permissions to match the view permissions, but you can separate them if needed (e.g., show a "log in to edit" button to anonymous users).

Configuration

Content & storage

KeyDefaultDescription
WIKI_HOME'home'Default page for /
WIKI_URL_PREFIX'/help'URL prefix for the wiki blueprint
WIKI_CONTENT_DIR'./data'Directory for Markdown files
WIKI_UPLOAD_FOLDER'./data/files'Directory for uploaded images
WIKI_ALLOWED_EXTENSIONS{'png','jpg','jpeg','gif','svg'}Allowed upload types
WIKI_INDEX_DIR'./index'Whoosh search index directory

Templates

All templates can be overridden by setting these config values to your own template paths:

KeyDefault
WIKI_BASE_TEMPLATE'wiki/base.html'
WIKI_PAGE_TEMPLATE'wiki/page.html'
WIKI_EDITOR_TEMPLATE'wiki/editor.html'
WIKI_SEARCH_TEMPLATE'wiki/search.html'
WIKI_FILES_TEMPLATE'wiki/files.html'
WIKI_NOT_FOUND_TEMPLATE'wiki/404.html'
WIKI_FORBIDDEN_TEMPLATE'wiki/403.html'

Internationalization

KeyDefaultDescription
WIKI_CURRENT_LANGUAGElambda: 'en'Callable returning the current language code
WIKI_LANGUAGES{'en': 'English', 'fr': 'French', 'de': 'German', 'it': 'Italian'}Available languages

Pages can have per-language variants using filename suffixes: page_fr.md, page_de.md, etc. The wiki automatically loads the correct variant based on WIKI_CURRENT_LANGUAGE.

Markdown

KeyDefaultDescription
WIKI_MARKDOWN_EXTENSIONS{'codehilite', 'fenced_code'}Additional Python-Markdown extensions

The extensions toc, meta, tables, and a built-in Bootstrap extension are always loaded.

Development

Requirements

  • Python >=3.10,<3.15
  • uv

Setup

git clone <repo-url>
cd flask-wiki
uv sync --frozen

Run the example app

cd examples
uv run flask flask_wiki init-index
uv run flask flask_wiki index
uv run flask run --debug
# Visit http://localhost:5000/help

Run tests

uv run poe run_tests

License

BSD 3-Clause. See LICENSE for details.