SoFunction
Updated on 2025-04-14

Quickly build a Markdown note publishing system with Python

Introduction: Why build your own knowledge blog

In the information age, everyone’s digital notes are a gold mine. Whether it is the solution manual of technicians, the research notes of scholars, or the experience summary of lifestyle experts, these fragmented knowledge needs to be systematically organized and presented. There are three major pain points in traditional notes:

  • Access restrictions: Local files are difficult to share across devices
  • Single format: plain text lacks structured expression
  • Search Difficulty: Lack of Semantic Labels and Full Text Search

This article will use mature tools of the Python ecosystem to build a private knowledge publishing system that supports Markdown rendering, classification tags, and full-text search within 30 minutes.

1. Technology selection: Minimalist development stack

Components Choose a plan Advantages description
Web Framework Flask Lightweight and flexible, easy to use the routing system
database SQLite Zero configuration, single file storage is suitable for personal use
Markdown analysis markdown2 Supports GFM expansion, high conversion efficiency
Front-end template Jinja2 Built-in template engine for seamless integration with Flask
Static resources Bootstrap 5 Responsive design, rich components
Search function Whoosh Pure Python implementation, no external services required

2. System architecture design

graph TD
A[User Request] --> B{Routing Processing}
B --> C[Home/Category Page]
B --> D[Article details page]
B --> E[Search interface]
C --> F[Markdown file reading]
D --> G[Database Query]
E --> H[Whoosh Index Query]
F --> I[markdown2 conversion]
I --> J[HTML Template Rendering]
    G --> K[Peewee ORM]
H --> L[index file]
J --> M[Bootstrap frontend]

3. Core code implementation (step-by-step analysis)

1. Project Initialization

mkdir md_blog && cd md_blog
python -m venv venv
source venv/bin/activate  # Linux/Mac
venv\Scripts\  # Windows
pip install flask markdown2 whoosh peewee

2. Basic routing settings ()

from flask import Flask, render_template
 
app = Flask(__name__)
 
@('/')
def index():
    # Get all article metadata    posts = get_all_posts()
    return render_template('', posts=posts)
 
@('/post/<slug>')
def show_post(slug):
    post = get_post_by_slug(slug)
    return render_template('', post=post)
 
if __name__ == '__main__':
    (debug=True)

3. Database Model ()

from peewee import SqliteDatabase, Model, TextField, DateTimeField
import datetime
 
db = SqliteDatabase('')
 
class Post(Model):
    title = TextField()
    slug = TextField(unique=True)
    content = TextField()
    created_at = DateTimeField(default=)
    tags = TextField()  # Separate storage with commas 
    class Meta:
        database = db
 
()
db.create_tables([Post])

4. Markdown processing tool (md_utils.py)

import markdown2
 
def md_to_html(content):
    extras = ["fenced-code-blocks", "tables", "strike"]
    return (content, extras=extras)

5. Template example (templates/)

{% extends "" %}
{% block content %}
<div class="container mt-4">
    <h1>{{  }}</h1>
    <div class="text-muted">
        {{ post.created_at.strftime('%Y-%m-%d') }}
        {% if  %}
        | Label:{% for tag in (',') %}
            <a href="/tag/{{ tag }}" rel="external nofollow"  class="badge bg-secondary">{{ tag }}</a>
        {% endfor %}
        {% endif %}
    </div>
    <hr>
    {{ post.content_html|safe }}
</div>
{% endblock %}

6. Full-text search implementation ()

from  import create_in
from  import *
import 
 
def create_index():
    schema = Schema(
        title=TEXT(stored=True),
        content=TEXT,
        path=ID(stored=True),
    )
    
    if not ("indexdir"):
        ("indexdir")
    
    ix = create_in("indexdir", schema)
    writer = ()
    
    # traverse all articles to the index    for post in ():
        writer.add_document(
            title=,
            content=,
            path=f"/post/{}"
        )
    ()

4. Advanced function expansion

1. Automatically generate summary

def generate_excerpt(html_content, max_length=200):
    from bs4 import BeautifulSoup
    soup = BeautifulSoup(html_content, '')
    text = soup.get_text()
    return text[:max_length] + '...' if len(text) > max_length else text

2. Article directory generation

def generate_toc(html_content):
    from bs4 import BeautifulSoup
    soup = BeautifulSoup(html_content, '')
    headers = soup.find_all(['h1','h2','h3'])
    
    toc = '<nav class="toc"><ul>'
    for h in headers:
        tag = 
        id = ('id', '')
        if not id:
            id = ().replace(' ', '-')[:20]
            h['id'] = id
        toc += f'<li><a href="#{id}" rel="external nofollow" >{}</a></li>'
    toc += '</ul></nav>'
    return toc

3. Deployment plan

Run locally: flask run --host=0.0.0.0 --port=8080

Production deployment:

pip install gunicorn
gunicorn -w 4 -b 0.0.0.0:8000 app:app

Nginx configuration:

server {
    listen 80;
    server_name your_domain.com;
    
    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

5. Usage skills and optimization suggestions

Batch import tool:

def import_from_folder(folder_path):
    for filename in (folder_path):
        if ('.md'):
            with open((folder_path, filename)) as f:
                content = ()
            # parse YAML header information            metadata, content = parse_yaml_header(content)
            (
                title=('title', filename[:-3]),
                slug=('slug', filename[:-3].lower()),
                content=content,
                tags=('tags', '')
            )

Performance optimization:

  • Enable Flask caching: from flask_caching import Cache
  • Use CDN to speed up static resources
  • Regular updates to search indexes

Security enhancement:

from flask_httpauth import HTTPTokenAuth
auth = HTTPTokenAuth(scheme='Bearer')
 
@auth.verify_token
def verify_token(token):
    return token == ('ACCESS_TOKEN')
 
@('/admin')
@auth.login_required
def admin_panel():
    return render_template('')

Conclusion: The ultimate solution to building a personal knowledge network

This Markdown blog system not only solves the problem of knowledge fragmentation, but also makes the personal knowledge base truly a reusable smart asset through structured storage and semantic retrieval. Developers only need to add modules such as authentication, comment system, RSS subscription, etc. on this basis to build a complete knowledge management platform.

This is the end of this article about using Python to quickly build a Markdown note publishing system. For more related content of the Python Markdown note publishing system, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!