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_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
FILEMAP = None
@ -53,6 +57,11 @@ class FileMap:
self.input_dir = Path(input_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
def _path_to_key(path):
return str(path)
@ -112,7 +121,8 @@ class FileMap:
include_index_entries=True):
post = {
'title': filepath.name,
'content_after_search': False,
'blog': False,
'content_after_search': None,
'automatic_index': True,
'search_bar': True,
'tags': [],
@ -125,6 +135,9 @@ class FileMap:
file_pointer).to_dict().items():
post[key] = val
if post['content_after_search'] is None:
post['content_after_search'] = post['blog']
if 'content' in post.keys():
post['content'] = render_markdown(post['content'])
@ -160,7 +173,7 @@ class FileMap:
return entries
def _get_file_properties(self, filepath):
post = {'title': filepath.name}
post = {'title': filepath.name, 'pub_date': False}
if filepath.suffix == '.md':
with open(filepath, encoding='utf-8') as file_pointer:
@ -257,6 +270,34 @@ def get_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):
"""
@ -278,7 +319,9 @@ def render_markdown_file(input_filepath):
uuid=properties.get("uuid"),
tags=properties.get("tags"),
author=properties.get("author"),
title=properties.get("title"))
title=properties.get("title"),
published=properties.get("pub_date")
)
properties['dst_path']['html'].write_text(html)
@ -476,22 +519,47 @@ def main(args):
root_properties = FILEMAP.get(root)
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)
html = JINJA_TEMPLATE_INDEX.render(
# render index
html = (JINJA_TEMPLATE_BLOGINDEX if root_properties['blog'] else JINJA_TEMPLATE_INDEX).render(
gronk_commit=GRONK_COMMIT,
title=root_properties.get('title', ''),
content=root_properties.get('content', ''),
content_after_search=root_properties['content_after_search'],
automatic_index=root_properties['automatic_index'],
search_bar=root_properties['search_bar'],
posts=posts,
index_entries=[{
'title': entry.get('title', ''),
'is_dir': entry.get('is_dir', False),
'path': str(entry.get('path', Path(''))),
} for entry in root_properties.get('index_entries', '')],
)
root_properties['dst_path']['raw'].joinpath('index.html').write_text(
html)
root_properties['dst_path']['raw'].joinpath('index.html').write_text(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
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:
| 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 |
| `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. |
| `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 |
|------------------|---------------------------------------------------------------------------------------|
| `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 |
| `title` | The title of the article |
| `uuid` | A unique identifier used for permalinks. |
| `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 |
## 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 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>
{% endif %}
{% if published %}
<p class="smallText metadata"> published: {{ published }} </p>
{% endif %}
<p class="smallText metadata"> tags: [
{% for tag in tags %}
<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>