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!