added tags functionality
This commit is contained in:
43
app.py
43
app.py
@@ -1,29 +1,46 @@
|
|||||||
from flask import Flask, render_template
|
from flask import Flask, render_template
|
||||||
from flask_flatpages import FlatPages
|
from flask_flatpages import FlatPages
|
||||||
|
|
||||||
DEBUG = True
|
|
||||||
FLATPAGES_AUTO_RELOAD = DEBUG
|
|
||||||
FLATPAGES_EXTENSION = '.md'
|
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.config.from_object(__name__)
|
|
||||||
pages = FlatPages(app)
|
# Consolidate Configs
|
||||||
|
app.config.update(
|
||||||
|
FLATPAGES_AUTO_RELOAD = True,
|
||||||
|
FLATPAGES_EXTENSION = '.md',
|
||||||
FLATPAGES_MARKDOWN_EXTENSIONS = ['fenced_code', 'tables']
|
FLATPAGES_MARKDOWN_EXTENSIONS = ['fenced_code', 'tables']
|
||||||
app.config['FLATPAGES_MARKDOWN_EXTENSIONS'] = FLATPAGES_MARKDOWN_EXTENSIONS
|
)
|
||||||
|
|
||||||
|
pages = FlatPages(app)
|
||||||
|
|
||||||
@app.route('/')
|
@app.route('/')
|
||||||
def index():
|
def index():
|
||||||
|
# Sort posts by date metadata
|
||||||
posts = sorted(pages, key=lambda p: p.meta.get('date'), reverse=True)
|
posts = sorted(pages, key=lambda p: p.meta.get('date'), reverse=True)
|
||||||
return render_template('index.html', posts=posts)
|
return render_template('index.html', posts=posts)
|
||||||
|
|
||||||
@app.route('/<path:path>/')
|
|
||||||
def post(path):
|
|
||||||
page = pages.get_or_404(path)
|
|
||||||
return render_template('post.html', page=page)
|
|
||||||
|
|
||||||
@app.route('/about')
|
@app.route('/about')
|
||||||
def about():
|
def about():
|
||||||
return render_template('about.html')
|
return render_template('about.html')
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/post/<path:path>/') # Adding /post/ prefix helps organize URLs
|
||||||
|
def post(path):
|
||||||
|
page = pages.get_or_404(path)
|
||||||
|
return render_template('post.html', page=page)
|
||||||
|
|
||||||
|
@app.route('/tag/<string:tag_name>/')
|
||||||
|
def tag(tag_name):
|
||||||
|
tagged_pages = [p for p in pages if tag_name in p.meta.get('tags', [])]
|
||||||
|
return render_template('tag.html', pages=tagged_pages, tag_name=tag_name)
|
||||||
|
|
||||||
|
@app.context_processor
|
||||||
|
def inject_tags():
|
||||||
|
all_tags = set()
|
||||||
|
for page in pages:
|
||||||
|
t = page.meta.get('tags', [])
|
||||||
|
if isinstance(t, list):
|
||||||
|
all_tags.update(t)
|
||||||
|
return dict(all_cloud_tags=sorted(list(all_tags)))
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
app.run(port=5001)
|
app.run(port=5001, debug=True)
|
||||||
@@ -4,5 +4,5 @@
|
|||||||
<section class="hero">
|
<section class="hero">
|
||||||
<h2 style="color: #2563eb">What is this site?</h2>
|
<h2 style="color: #2563eb">What is this site?</h2>
|
||||||
</section>
|
</section>
|
||||||
I write articles about Arduino, STM32 and self-hosting. The articles are short and conceptual. It is not tutorials but more high level descriptions and general guidelines for reproducing the various things i tinker with.
|
I write articles about Arduino, STM32 and Self-hosting. The articles are short and conceptual. It is not tutorials but more high level descriptions and general guidelines for reproducing the various things i tinker with.
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
<nav class="container">
|
<nav class="container">
|
||||||
@@ -22,13 +23,29 @@
|
|||||||
</header>
|
</header>
|
||||||
|
|
||||||
<main class="container">
|
<main class="container">
|
||||||
|
<div class="layout-wrapper">
|
||||||
|
<section class="content-area">
|
||||||
{% block content %}{% endblock %}
|
{% block content %}{% endblock %}
|
||||||
</main>
|
</section>
|
||||||
|
|
||||||
|
<aside class="sidebar">
|
||||||
|
<div class="sidebar-section">
|
||||||
|
<h3>Tags</h3>
|
||||||
|
<ul class="tag-list">
|
||||||
|
{% for tag in all_cloud_tags %}
|
||||||
|
<li><a href="{{ url_for('tag', tag_name=tag) }}">#{{ tag }}</a></li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
<footer>
|
<footer>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
|
<script
|
||||||
|
src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
@@ -2,16 +2,25 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<section class="hero">
|
<section class="hero">
|
||||||
<h2 style="color: #2563eb; margin-bottom : 10%">I write about Self-hosting, Arduino, STM32 and various tech stupidity.</h2>
|
<h2 style="color: #2563eb; margin-bottom : 10%">I write about Self-hosting, Arduino, STM32.</h2>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<div class="post-list">
|
<div class="post-list">
|
||||||
{% for post in posts %}
|
{% for post in posts %}
|
||||||
<article class="post-item">
|
<article class="post-item">
|
||||||
<h3><a href="{{ url_for('post', path=post.path) }}">{{ post.title }}</a></h3>
|
<h3>
|
||||||
|
<a href="{{ url_for('post', path=post.path) }}" class="main-link">
|
||||||
|
{{ post.title }}
|
||||||
|
</a>
|
||||||
|
</h3>
|
||||||
<span class="date">{{ post.date }}</span>
|
<span class="date">{{ post.date }}</span>
|
||||||
<p>{{ post.meta.get('description', 'Read more...') }}</p>
|
<p>{{ post.meta.get('description', 'Read more...') }}</p>
|
||||||
<p>{{ post.meta.get('tag', 'no tag') }}</p>
|
|
||||||
|
<div class="tags" style="position: relative; z-index: 2;">
|
||||||
|
{% for tag in post.meta.get('tags', []) %}
|
||||||
|
<a href="{{ url_for('tag', tag_name=tag) }}" class="tag-badge">#{{ tag }}</a>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
</article>
|
</article>
|
||||||
{% else %}
|
{% else %}
|
||||||
<p>No posts yet. Time to write something!</p>
|
<p>No posts yet. Time to write something!</p>
|
||||||
|
|||||||
@@ -5,5 +5,10 @@
|
|||||||
<p class="date">{{ page.date }}</p>
|
<p class="date">{{ page.date }}</p>
|
||||||
<div class="post-body">
|
<div class="post-body">
|
||||||
{{ page.html|safe }} </div>
|
{{ page.html|safe }} </div>
|
||||||
|
{% for t in page.tags %}
|
||||||
|
<a href="{{ url_for('tag', tag_name=t) }}">{{ t }}</a>{% if not loop.last %}, {% endif %}
|
||||||
|
{% endfor %}
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
16
templates/tag.html
Normal file
16
templates/tag.html
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h2>Posts tagged with "{{ tag_name }}"</h2>
|
||||||
|
|
||||||
|
<div class="post-list">
|
||||||
|
{% for p in pages %}
|
||||||
|
<article class="post-item">
|
||||||
|
<h3><a href="{{ url_for('post', path=p.path) }}">{{ p.title }}</a></h3>
|
||||||
|
<span class="date">{{ p.date }}</span>
|
||||||
|
</article>
|
||||||
|
{% else %}
|
||||||
|
<p>No posts found with this tag.</p>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
Reference in New Issue
Block a user