Refactored blog home template

This commit is contained in:
Fabio Manganiello 2021-01-24 23:24:49 +01:00
parent d81abaa984
commit b8df9f73a0
8 changed files with 286 additions and 113 deletions

View file

@ -1,11 +1,12 @@
import datetime
import os
import re
from glob import glob
from typing import Optional
from markdown import markdown
from flask import Flask, abort, send_from_directory, render_template
from markdown import markdown
basedir = os.path.abspath(os.path.join(os.path.realpath(__file__), '..', '..'))
templates_dir = os.path.join(basedir, 'templates')
@ -33,6 +34,8 @@ def get_page_metadata(page: str) -> dict:
metadata = {}
with open(os.path.join(pages_dir, page), 'r') as f:
metadata['uri'] = '/article/' + page[:-3]
for line in f.readlines():
if not line:
continue
@ -40,7 +43,10 @@ def get_page_metadata(page: str) -> dict:
if not (m := re.match(r'^\[//]: # \(([^:]+):\s*([^)]+)\)\s*$', line)):
break
metadata[m.group(1)] = m.group(2)
if m.group(1) == 'published':
metadata[m.group(1)] = datetime.date.fromisoformat(m.group(2))
else:
metadata[m.group(1)] = m.group(2)
return metadata
@ -52,15 +58,27 @@ def get_page(page: str, title: Optional[str] = None):
metadata = get_page_metadata(page)
with open(os.path.join(pages_dir, page), 'r') as f:
return render_template('article.html',
title=title if title else metadata.get('title', 'Platypush Blog'),
published=(datetime.date.fromisoformat(metadata['published']).strftime('%b %d, %Y')
title=title if title else metadata.get('title', 'Platypush blog'),
image=metadata.get('image'),
description=metadata.get('description'),
published=(metadata['published'].strftime('%b %d, %Y')
if metadata.get('published') else None),
content=markdown(f.read(),extensions=['fenced_code', 'codehilite']))
def get_pages() -> list:
return sorted([
{
'path': path,
**get_page_metadata(os.path.basename(path)),
}
for path in glob(os.path.join(pages_dir, '*.md'))
], key=lambda page: page.get('published'), reverse=True)
@app.route('/', methods=['GET'])
def home_route():
return get_page('Home', title='Platypush Blog')
return render_template('index.html', pages=get_pages())
@app.route('/favicon.ico', methods=['GET'])
@ -78,9 +96,6 @@ def css_route(style: str):
return send_from_directory(css_dir, style)
@app.route('/<path:path>', methods=['GET'])
def catch_all(path: str):
if path.endswith('.md'):
return get_page(path)
abort(404)
@app.route('/article/<article>', methods=['GET'])
def article_route(article: str):
return get_page(article)

View file

@ -1,114 +1,40 @@
html {
font-size: calc(1em + 1vw);
}
@media screen and (min-width: 1024px) {
html {
font-size: 20px;
}
}
body {
margin: 0;
width: 100%;
height: 100%;
}
a, a:visited {
color: #555;
border-bottom: 1px dashed #999;
text-decoration: none;
}
a:hover {
opacity: 0.7;
}
header {
display: flex;
align-items: center;
height: 3em;
padding: 0 .5em;
box-shadow: 1px 3px 3px 0 #bbb;
}
@media screen and (max-width: 767px) {
header {
height: 4em;
}
}
header > a {
display: flex;
align-items: center;
border-bottom: none;
}
header .icon {
background: url(/img/icon.png);
background-size: 40px;
width: 40px;
height: 40px;
display: inline-flex;
margin-right: 1em;
}
header .title {
display: inline-flex;
}
main {
height: calc(100% - 3em);
overflow: auto;
display: flex;
flex-direction: column;
align-items: center;
font-family: Avenir, Palatino, Georgia, Verdana, Helvetica, Arial, sans-serif;
padding: 0 2em;
}
main .content {
display: flex;
flex-direction: column;
text-align: justify;
line-height: 1.5em;
letter-spacing: .04em;
display: flex;
flex-direction: column;
text-align: justify;
line-height: 1.5em;
letter-spacing: .04em;
}
main .content code, .codehilite {
font-size: .85em;
font-size: .85em;
}
h1 {
font-size: 2em;
line-height: 1.2em;
}
h2 {
font-size: 1.5em;
line-height: 1.1em;
.description h3 {
font-weight: normal;
opacity: 0.6;
margin: -.5em auto .5em auto;
}
.published-date {
font-size: 0.75em;
opacity: .75;
margin-top: -1em;
margin-bottom: 2em;
font-size: 0.75em;
opacity: .75;
margin-bottom: 2em;
}
@media screen and (max-width: 1024px) {
main .content, main .title {
width: 100%;
}
main .container {
width: 100%;
}
}
@media screen and (min-width: 1024px) {
main .content, main .title {
max-width: 768px;
}
main .container {
max-width: 768px;
}
}
.codehilite {
padding: 0 .5em;
overflow: auto;
padding: 0 .5em;
overflow: auto;
}

78
static/css/common.css Normal file
View file

@ -0,0 +1,78 @@
html {
font-size: calc(1em + 1vw);
}
@media screen and (min-width: 1024px) {
html {
font-size: 20px;
}
}
body {
margin: 0;
width: 100%;
height: 100%;
}
a, a:visited {
color: #555;
border-bottom: 1px dashed #999;
text-decoration: none;
}
a:hover {
opacity: 0.7;
}
header {
display: flex;
align-items: center;
height: 3em;
padding: 0 .5em;
box-shadow: 1px 3px 3px 0 #bbb;
}
@media screen and (max-width: 767px) {
header {
height: 4em;
}
}
header > a {
display: flex;
align-items: center;
border-bottom: none;
}
header .icon {
background: url(/img/icon.png);
background-size: 40px;
width: 40px;
height: 40px;
display: inline-flex;
margin-right: 1em;
}
header .title {
display: inline-flex;
}
main {
height: calc(100% - 3em);
overflow: auto;
display: flex;
flex-direction: column;
align-items: center;
font-family: Avenir, Palatino, Georgia, Verdana, Helvetica, Arial, sans-serif;
padding: 0 2em;
}
h1 {
font-size: 2em;
line-height: 1.2em;
}
h2 {
font-size: 1.5em;
line-height: 1.1em;
}

94
static/css/home.css Normal file
View file

@ -0,0 +1,94 @@
main {
padding: 0;
}
.articles {
width: 100%;
display: flex;
}
.article {
display: block;
box-shadow: 0 1px 3px 1px #ddd;
overflow: hidden;
text-overflow: ellipsis;
max-height: 30em;
color: black !important;
}
.article:hover {
box-shadow: 0 1px 4px 2px #bcbcbc;
}
@media screen and (max-width: 767px) {
.article {
width: 100%;
}
}
@media screen and (min-width: 768px) and (max-width: 990px) {
.article {
width: 50%;
}
}
@media screen and (min-width: 990px) and (max-width: 1023px) {
.article {
width: 33%;
}
}
@media screen and (min-width: 1024px) and (max-width: 1279px) {
.article {
width: 25%;
}
}
@media screen and (min-width: 1280px) {
.article {
width: 20%;
}
}
.article .container {
height: 100%;
padding: 2em;
}
.image {
height: 35%;
z-index: 1;
}
.image img {
width: 100%;
height: 100%;
}
.article .title {
font-size: 1.2em;
font-weight: bold;
margin-top: .4em;
text-align: center;
}
a {
border-bottom: 0;
}
.description {
color: rgba(0, 0, 0, 0.7);
font-size: .9em;
}
.published-date {
font-size: .8em;
color: rgba(0, 0, 0, 0.4);
margin: .5em 0 2em 0;
text-align: center;
}
h3 {
margin: 40px 0 0;
}

BIN
static/img/dashboard-1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 727 KiB

View file

@ -1,4 +1,6 @@
[//]: # (title: Ultimate self-hosted automation with Platypush)
[//]: # (description: Get started with Platypush to automate your smart home and beyond)
[//]: # (image: /img/dashboard-1.png)
[//]: # (published: 2019-07-28)
In the last few years we have experienced a terrific spike of products and solutions targeting home automation and

View file

@ -1,5 +1,6 @@
<html lang="en">
<head>
<link rel="stylesheet" type="text/css" href="/css/common.css">
<link rel="stylesheet" type="text/css" href="/css/blog.css">
<link rel="stylesheet" type="text/css" href="/css/code.css">
<title>{{ title }}</title>
@ -9,22 +10,31 @@
<header>
<a href="/">
<div class="icon"></div>
<div class="title">Platypush Blog</div>
<div class="title">Platypush blog</div>
</a>
</header>
<main>
<div class="title">
<h1>{{ title }}</h1>
<div class="container">
<div class="title">
<h1>{{ title }}</h1>
</div>
{% if description %}
<div class="description">
<h3>{{ description }}</h3>
</div>
{% endif %}
{% if published %}
<div class="published-date">
Published on {{ published }}
</div>
{% endif %}
</div>
<div class="content">
{{ content | safe }}
<div class="content">
{{ content | safe }}
</div>
</div>
</main>
</body>

48
templates/index.html Normal file
View file

@ -0,0 +1,48 @@
<html lang="en">
<head>
<link rel="stylesheet" type="text/css" href="/css/common.css">
<link rel="stylesheet" type="text/css" href="/css/home.css">
<title>Platypush blog</title>
</head>
<body>
<header>
<a href="/">
<div class="icon"></div>
<div class="title">Platypush blog</div>
</a>
</header>
<main>
<div class="articles">
{% for page in pages %}
<a class="article" href="{{ page['uri'] }}">
<div class="container">
{% if page['image'] %}
<div class="image">
<img src="{{ page['image'] }}" alt="">
</div>
{% endif %}
<div class="title">
{{ page['title'] }}
</div>
{% if page['published'] %}
<div class="published-date">
{{ page['published'].strftime('%b %d, %Y') }}
</div>
{% endif %}
{% if page['description'] %}
<div class="description">
{{ page['description'] }}
</div>
{% endif %}
</div>
</a>
{% endfor %}
</div>
</main>
</body>
</html>