add blog mode

This commit is contained in:
Akbar Rahman 2024-04-13 19:53:51 +01:00
parent c59283b3fc
commit f23f99aeec
Signed by: alvierahman90
GPG Key ID: 6217899F07CA2BDF
6 changed files with 238 additions and 13 deletions

View File

@ -38,6 +38,10 @@ JINJA_TEMPLATE_INDEX = JINJA_ENV.get_template("index.html")
JINJA_TEMPLATE_ARTICLE = JINJA_ENV.get_template("article.html") JINJA_TEMPLATE_ARTICLE = JINJA_ENV.get_template("article.html")
JINJA_TEMPLATE_PERMALINK = JINJA_ENV.get_template("permalink.html") JINJA_TEMPLATE_PERMALINK = JINJA_ENV.get_template("permalink.html")
JINJA_TEMPLATE_BLOGINDEX = JINJA_ENV.get_template("blog_index.html")
JINJA_TEMPLATE_BLOG_INLINE_POST = JINJA_ENV.get_template("blog_inline_post.html")
JINJA_TEMPLATE_BLOG_FEED = JINJA_ENV.get_template("rss.xml")
LICENSE = None LICENSE = None
FILEMAP = None FILEMAP = None
@ -53,6 +57,11 @@ class FileMap:
self.input_dir = Path(input_dir) self.input_dir = Path(input_dir)
self.output_dir = Path(output_dir) self.output_dir = Path(output_dir)
def get_base_url(self):
props = self.get(self.input_dir.joinpath('readme.md'))
print(props)
return props['base_url']
@staticmethod @staticmethod
def _path_to_key(path): def _path_to_key(path):
return str(path) return str(path)
@ -112,7 +121,8 @@ class FileMap:
include_index_entries=True): include_index_entries=True):
post = { post = {
'title': filepath.name, 'title': filepath.name,
'content_after_search': False, 'blog': False,
'content_after_search': None,
'automatic_index': True, 'automatic_index': True,
'search_bar': True, 'search_bar': True,
'tags': [], 'tags': [],
@ -125,6 +135,9 @@ class FileMap:
file_pointer).to_dict().items(): file_pointer).to_dict().items():
post[key] = val post[key] = val
if post['content_after_search'] is None:
post['content_after_search'] = post['blog']
if 'content' in post.keys(): if 'content' in post.keys():
post['content'] = render_markdown(post['content']) post['content'] = render_markdown(post['content'])
@ -160,7 +173,7 @@ class FileMap:
return entries return entries
def _get_file_properties(self, filepath): def _get_file_properties(self, filepath):
post = {'title': filepath.name} post = {'title': filepath.name, 'pub_date': False}
if filepath.suffix == '.md': if filepath.suffix == '.md':
with open(filepath, encoding='utf-8') as file_pointer: with open(filepath, encoding='utf-8') as file_pointer:
@ -257,6 +270,34 @@ def get_args():
) )
return parser.parse_args() return parser.parse_args()
def render_inline_blog_post(input_filepath):
"""
render markdown file as blog post for inlinining into blog index
returns html
"""
with open(input_filepath, encoding='utf-8') as file_pointer:
content = frontmatter.load(file_pointer).content
properties = FILEMAP.get(input_filepath)
html = render_markdown(content)
html = JINJA_TEMPLATE_BLOG_INLINE_POST.render(
license=LICENSE,
content=html,
lecture_slides=properties.get("lecture_slides"),
lecture_notes=properties.get("lecture_notes"),
uuid=properties.get("uuid"),
tags=properties.get("tags"),
author=properties.get("author"),
title=properties.get("title"),
published=properties.get("pub_date"),
base_url=FILEMAP.get_base_url(),
)
properties['dst_path']['html'].write_text(html)
return html
def render_markdown_file(input_filepath): def render_markdown_file(input_filepath):
""" """
@ -278,7 +319,9 @@ def render_markdown_file(input_filepath):
uuid=properties.get("uuid"), uuid=properties.get("uuid"),
tags=properties.get("tags"), tags=properties.get("tags"),
author=properties.get("author"), author=properties.get("author"),
title=properties.get("title")) title=properties.get("title"),
published=properties.get("pub_date")
)
properties['dst_path']['html'].write_text(html) properties['dst_path']['html'].write_text(html)
@ -476,22 +519,47 @@ def main(args):
root_properties = FILEMAP.get(root) root_properties = FILEMAP.get(root)
root_properties['dst_path']['raw'].mkdir(parents=True, exist_ok=True) root_properties['dst_path']['raw'].mkdir(parents=True, exist_ok=True)
posts = []
if root_properties['blog']:
for file in files:
props = FILEMAP.get(root.joinpath(file))
post = {
'title': props['title'],
'link': props['dst_path']['web'],
'pub_date': props.get('pub_date'),
'description': render_inline_blog_post(root.joinpath(file)),
}
posts.append(post)
#pprint.pprint(root_properties) #pprint.pprint(root_properties)
html = JINJA_TEMPLATE_INDEX.render( # render index
html = (JINJA_TEMPLATE_BLOGINDEX if root_properties['blog'] else JINJA_TEMPLATE_INDEX).render(
gronk_commit=GRONK_COMMIT, gronk_commit=GRONK_COMMIT,
title=root_properties.get('title', ''), title=root_properties.get('title', ''),
content=root_properties.get('content', ''), content=root_properties.get('content', ''),
content_after_search=root_properties['content_after_search'], content_after_search=root_properties['content_after_search'],
automatic_index=root_properties['automatic_index'], automatic_index=root_properties['automatic_index'],
search_bar=root_properties['search_bar'], search_bar=root_properties['search_bar'],
posts=posts,
index_entries=[{ index_entries=[{
'title': entry.get('title', ''), 'title': entry.get('title', ''),
'is_dir': entry.get('is_dir', False), 'is_dir': entry.get('is_dir', False),
'path': str(entry.get('path', Path(''))), 'path': str(entry.get('path', Path(''))),
} for entry in root_properties.get('index_entries', '')], } for entry in root_properties.get('index_entries', '')],
) )
root_properties['dst_path']['raw'].joinpath('index.html').write_text( root_properties['dst_path']['raw'].joinpath('index.html').write_text(html)
html)
# render rss feed if blog
if root_properties['blog']:
rss = JINJA_TEMPLATE_BLOG_FEED.render(
title=root_properties.get('title', ''),
description=root_properties.get('content', ''),
base_url=FILEMAP.get_base_url(),
link=f"{FILEMAP.get_base_url()}{root_properties['dst_path']['web']}",
language='en-GB',
posts=posts,
)
root_properties['dst_path']['raw'].joinpath('feed.xml').write_text(rss)
# render each file # render each file
for file in files: for file in files:

View File

@ -58,10 +58,11 @@ To add custom content to a directory index, put it in a file called `readme.md`
You can set the following frontmatter variables to customise the directory index of a directory: You can set the following frontmatter variables to customise the directory index of a directory:
| variable | default value | description | | variable | default value | description |
|------------------------|-------------------|--------------------------------------------------------------------------------------------| |------------------------|----------------|--------------------------------------------------------------------------------------------|
| `blog` | `false` | enable [blog mode](#blog-mode) for this directory |
| `tags` | `[]` | list of tags, used by search and inherited by any notes and subdirectories | | `tags` | `[]` | list of tags, used by search and inherited by any notes and subdirectories |
| `uuid` | none | unique id to reference directory, used for permalinking | | `uuid` | none | unique id to reference directory, used for permalinking |
| `content_after_search` | `false` | show custom content in `readme.md` after search bar and directory index | | `content_after_search` | same as `blog` | show custom content in `readme.md` after search bar and directory index |
| `automatic_index` | `true` | show the automatically generated directory index. required for search bar to function. | | `automatic_index` | `true` | show the automatically generated directory index. required for search bar to function. |
| `search_bar` | `true` | show search bar to search directory items. requires `automatic_index` (enabled by default) | | `search_bar` | `true` | show search bar to search directory items. requires `automatic_index` (enabled by default) |
@ -73,12 +74,21 @@ gronk reads the following YAML [frontmatter](https://jekyllrb.com/docs/front-mat
| variable | description | | variable | description |
|------------------|---------------------------------------------------------------------------------------| |------------------|---------------------------------------------------------------------------------------|
| `author` | The person(s) who wrote the article | | `author` | The person(s) who wrote the article |
| `pub_date` | set the publish date of an article/post/note |
| `tags` | A YAML list of tags which the article relates to - this is used for browsing and also | | `tags` | A YAML list of tags which the article relates to - this is used for browsing and also |
| `title` | The title of the article | | `title` | The title of the article |
| `uuid` | A unique identifier used for permalinks. | | `uuid` | A unique identifier used for permalinks. |
| `lecture_slides` | a list of paths pointing to lecture slides used while taking notes | | `lecture_slides` | a list of paths pointing to lecture slides used while taking notes |
| `lecture_notes` | a list of paths pointing to other notes used while taking notes | | `lecture_notes` | a list of paths pointing to other notes used while taking notes |
## Blog Mode
A directory can be turned into a blog by enabling blog mode.
This can be done by setting the `blog` variable to `true` in the `readme.md` [custom directory metadata](#custom-directory-index-and-metadata).
Notes under this directory will be published to a blog, whose feed is accesible at `https://notes.alv.cx/notes/<directory..>/feed.xml`.
## Permalinks ## Permalinks
Permalinks are currently rather basic and requires JavaScript to be enabled on the local computer. Permalinks are currently rather basic and requires JavaScript to be enabled on the local computer.

View File

@ -32,6 +32,10 @@
<p class="smallText metadata"> uuid: {{ uuid }} (<a href="/permalink?uuid={{ uuid }}">permalink</a>) </p> <p class="smallText metadata"> uuid: {{ uuid }} (<a href="/permalink?uuid={{ uuid }}">permalink</a>) </p>
{% endif %} {% endif %}
{% if published %}
<p class="smallText metadata"> published: {{ published }} </p>
{% endif %}
<p class="smallText metadata"> tags: [ <p class="smallText metadata"> tags: [
{% for tag in tags %} {% for tag in tags %}
<a href="/tags/{{ tag }}">{{ tag }}</a>{% if loop.nextitem %},{% endif %} <a href="/tags/{{ tag }}">{{ tag }}</a>{% if loop.nextitem %},{% endif %}

78
templates/blog_index.html Normal file
View File

@ -0,0 +1,78 @@
{% extends "base.html" %}
{% block head %}
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
<script>
MathJax = {
tex: {
tags: 'ams'
}
}
</script>
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
{% endblock %}
{% block content %}
<p class="smallText metadata">
syntax highlighting based on <a href="https://pygments.org/">Pygments'</a> default
colors
</p>
<p class="smallText metadata">
page generated by <a href="https://git.alv.cx/alvierahman90/gronk">gronk</a>
</p>
<p class="smallText metadata">
<a href="./feed.xml">rss feed</a>
</p>
{% if license %}
<details id="license">
<summary class="smallText">
License
</summary>
<pre>{{ license }}</pre>
</details>
{% endif %}
<h1>{{ title }}</h1>
{% if not content_after_search %}
{{ content|safe }}
{% for post in posts %}
{{ post['description']|safe }}
{% endfor %}
{% endif %}
{% if automatic_index %}
<details>
<summary>
<h2> List of posts </h2>
</summary>
{% if search_bar %}
<div id="searchWrapper">
<input id="search" placeholder="search" autocomplete="off" autofocus>
</div>
<p class="searchSmallText" style="margin-top: 0; text-align: center">
Press (<kbd>Shift</kbd>+)<kbd>Enter</kbd> to open first result (in new tab)
</p>
{% endif %}
<ul id="searchResults" class="buttonlist">
<li class="article"><a href=".."><p>../</p></a></li>
{% for entry in index_entries %}
<li class="article"><a href="{{ entry['path'] }}"><p>{{ entry['title'] }}{% if entry['is_dir'] %}/{% endif %}</p></a></li>
{% endfor %}
</ul>
</details>
{% endif %}
{% if content_after_search %}
{{ content|safe }}
{% for post in posts %}
{{ post['description']|safe }}
{% endfor %}
{% endif %}
<script src="/js/fuse.js"> </script>
<script> const search_data = {{ index_entries|tojson }} </script>
<script src="/js/indexsearch.js"> </script>
{% endblock %}

View File

@ -0,0 +1,42 @@
{% block content %}
<p class="smallText metadata"> title: {{ title }} </p>
{% if lecture_slides %}
<p class="smallText metadata"> lecture_slides: [
{% for slide in lecture_slides %}
<a href="{{ base_url}}{{ slide }}">{{ slide }}</a>{% if loop.nextitem %},{% endif %}
{% endfor %}
]</p>
{% endif %}
{% if lecture_notes %}
<p class="smallText metadata"> lecture_notes: [
{% for note in lecture_notes %}
<a href="{{ base_url }}{{ note }}">{{ note }}</a>{% if loop.nextitem %},{% endif %}
{% endfor %}
]</p>
{% endif %}
{% if uuid %}
<p class="smallText metadata"> uuid: {{ uuid }} (<a href="{{ base_url }}/permalink?uuid={{ uuid }}">permalink</a>) </p>
{% endif %}
{% if published %}
<p class="smallText metadata"> published: {{ published }} </p>
{% endif %}
<p class="smallText metadata"> tags: [
{% for tag in tags %}
<a href="{{ base_url }}/tags/{{ tag }}">{{ tag }}</a>{% if loop.nextitem %},{% endif %}
{% endfor %}
]</p>
<p class="smallText metadata">
{% if author is string %}
written by: {{ author }}
{% elif author is iterable %}
written by: [ {% for auth in author %}{{ auth }}{% if loop.nextitem %}, {% endif %}{% endfor %} ]
{% endif %}
</p>
{% block body_content %}
{{ content|safe }}
{% endblock %}
{% endblock %}

23
templates/rss.xml Normal file
View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>{{ title }}</title>
<description>{{ description }}</description>
<language>{{ language }}</language>
<link>{{ link }}</link>
<atom:link href="{{ link }}/feed.xml" rel="self" type="application/rss+xml" />
{% for post in posts %}
<item>
<title>{{ post['title']}}</title>
<guid>{{ base_url }}{{ post['link'] }}</guid>
{% if post['pub_date'] %}
<pubDate>{{ post['pub_date'] }}</pubDate>
{% endif %}
<description><![CDATA[{{ post['description']|safe }}]]></description>
</item>
{% endfor %}
</channel>
</rss>