mirror of
				https://github.com/alvierahman90/gronk.git
				synced 2025-10-31 07:10:07 +00:00 
			
		
		
		
	add blog mode
This commit is contained in:
		
							
								
								
									
										80
									
								
								gronk.py
									
									
									
									
									
								
							
							
						
						
									
										80
									
								
								gronk.py
									
									
									
									
									
								
							| @@ -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: | ||||||
|   | |||||||
							
								
								
									
										14
									
								
								readme.md
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								readme.md
									
									
									
									
									
								
							| @@ -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. | ||||||
|   | |||||||
| @@ -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
									
								
							
							
						
						
									
										78
									
								
								templates/blog_index.html
									
									
									
									
									
										Normal 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 %} | ||||||
							
								
								
									
										42
									
								
								templates/blog_inline_post.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								templates/blog_inline_post.html
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										23
									
								
								templates/rss.xml
									
									
									
									
									
										Normal 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> | ||||||
		Reference in New Issue
	
	Block a user