Skip to content

Commit

Permalink
* Add ids to the sections in the template
Browse files Browse the repository at this point in the history
* Make more settings configurable
* Provide settings to disable optional functionality
* More improvements to the README.rst
* Changed the project description to say "views" instead of "templates"
  • Loading branch information
rgs258 committed Jul 9, 2020
1 parent eccd12b commit 565fe11
Show file tree
Hide file tree
Showing 8 changed files with 153 additions and 48 deletions.
8 changes: 6 additions & 2 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
Changelog
=========

0.0.3 (2020-07-08)
0.0.3 (2020-07-09)
------------------
#. Correct a typo the README.rst
#. Add settings to the README.rst
#. Add ids to the sections in the template
#. Make more settings configurable
#. Provide settings to disable optional functionality
#. Add settings to, and generally improve, the README.rst
#. Changed the project description to say "views" instead of "templates"

0.0.2 (2020-07-06)
------------------
Expand Down
110 changes: 87 additions & 23 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
Django Markdown View
====================

**Serve .md pages as Django templates.**
**Serve .md pages as Django views.**

This package aims to make it easy to serve .md files on Django sites.


.. contents:: Contents
:depth: 5

.. note::
* The Tested With section describes aspirational goals.
* Really, all directions describe aspirational goals.
* This package needs tests, and to have Travis properly configured.

Requirements
------------
Expand Down Expand Up @@ -45,7 +47,9 @@ Installation
]
#. (OPTIONAL) Add ``MARKDOWN_VIEW_BASE_DIR`` or ``BASE_DIR`` to settings
The dictionary of the application's base. For example:
The dictionary of the application's base. See Settings_ below

For example, if settings are in config/settings/base.py, then:

.. code-block:: python
Expand All @@ -72,49 +76,109 @@ from ``markdown_view.views`` to serve a .md file
Settings
~~~~~~~~
All settings are optional. See **markdown_view/constants.py** for the defaults.
All settings are optional. See `<markdown_view/constants.py>`_ for the defaults.

* `MARKDOWN_VIEW_BASE_DIR` and `BASE_DIR`

When present, the location to append to the list of dirs that Django's
`django.template.utils.get_app_template_dirs` will return. Looks for
`BASE_DIR` if `MARKDOWN_VIEW_BASE_DIR` is not found. This is used to
allow .md files in the root of the project to be located.
When present, the value is taken as a location to append to the list of dirs that
Django's `django.template.utils.get_app_template_dirs` will return when passed
`dirname=""`. This is used to locate .md files in the root of the project, e.g.,
a README.md file. Looks for `BASE_DIR` if `MARKDOWN_VIEW_BASE_DIR` is not found.

* `MARKDOWN_VIEW_LOADERS`

The loader that finds .md files in the context of any installed app or
one of `MARKDOWN_VIEW_BASE_DIR` or `BASE_DIR`.
A list of loaders that locate .md files. The default list includes only
`markdown_view.loaders.MarkdownLoader` which will by default try to load .md files
from root directories in INSTALLED_APPS packages much the same as Django's
`django.template.loaders.app_directories.Loader` looks to load from "templates".

* `MARKDOWN_VIEW_LOADER_TEMPLATES_DIR`

The name of the directories in INSTALLED_APPS packages in which to locate .md
files. Defaults to "" in order to locate .md filed in the root directories.

* `MARKDOWN_VIEW_EXTENSIONS`

The extensions to enable. These extensions are enabled be default:

* `DEFAULT_MARKDOWN_VIEW_EXTENSIONS`
* `toc`:
generates a Table of Contents. If `toc` is removed from extensions, then
`MARKDOWN_VIEW_TEMPLATE_USE_TOC` must be set to False.

The extensions to enable. See https://python-markdown.github.io/extensions/ and
* `tables`:
enables tables.

* `fenced_code`:
enables code blocks. If `fenced_code` is removed from extensions, then
`MARKDOWN_VIEW_TEMPLATE_USE_HIGHLIGHT_JS`, which provides the highlighting for
code blocks, can be disabled.

* `markdown_view.markdown_extensions.ImageExtension`:
makes images responsive in bootstrap4.

See https://python-markdown.github.io/extensions/ and
https://github.com/Python-Markdown/markdown/wiki/Third-Party-Extensions for more
extensions. Note that `markdown_view.markdown_extensions.ImageExtension` is enabled
and makes images responsive in bootstrap4. You can add you own extensions by
following https://github.com/Python-Markdown/markdown/wiki/Tutorial-1---Writing-Extensions-for-Python-Markdown
extensions.

* `DEFAULT_MARKDOWN_VIEW_TEMPLATE`
You can create your own extensions by following
https://github.com/Python-Markdown/markdown/wiki/Tutorial-1---Writing-Extensions-for-Python-Markdown

* `MARKDOWN_VIEW_TEMPLATE`

The Django template that'll be used to render the HTML that is generated from the
Markdown. Set your own template to style your pages. Context includes:

* `markdown_content`: The HTML produced from the Markdown
* `markdown_toc`: A table of contents from the headers of the Markdown
* `page_title`: A guess at a page title, for now it's the first row of the TOC
* `markdown_content`:
The HTML produced from the Markdown.

* `use_highlight_js`:
If highlight.js is enabled.

* `use_toc`:
If the table of contents should be rendered.

* `markdown_toc`:
A table of contents from the headers of the Markdown. Not set when `use_toc`
is False.

* `page_title`:
A guess at a page title, for now it's the first row of the TOC. Not set when
`use_toc` is False.

* `MARKDOWN_VIEW_TEMPLATE_USE_TOC`

Whether to render the TOC. If false, in the template context, `use_toc` is False
and `markdown_toc` and `page_title` are not present.

* `MARKDOWN_VIEW_TEMPLATE_USE_HIGHLIGHT_JS`

Whether to load and activate the highlight.js library in the template.

Experimental Settings
~~~~~~~~~~~~~~~~~~~~~

* `DEFAULT_MARKDOWN_VIEW_USE_REQUEST_CONTEXT`
* `MARKDOWN_VIEW_USE_REQUEST_CONTEXT`

If the request context should be used as a base when creating the context with
which to render the Markdown internally. This is because the Markdown is rendered
once first in order to prepend it with `{% load static %}`.
This is not well tested; YMMV.

* `DEFAULT_MARKDOWN_VIEW_EXTRA_CONTEXT`
* `MARKDOWN_VIEW_EXTRA_CONTEXT`

Any extra context to send to the internal render of the Markdown. Can be used
to expose context to template tags embedded in the Markdown.
This is not well tested; YMMV.
This is not well tested; YMMV.


Implementation
--------------

At a high level, `MarkdownView` will:

#. Use a template loader to locate .md given as `file_name`

#. Render as a template, the contents of the .md file prepended with
`{{% load static %}}`, into several context variables

#. Serve the `MARKDOWN_VIEW_TEMPLATE` with the context variables
3 changes: 3 additions & 0 deletions markdown_view/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@

SETTINGS_TYPES = {
"MARKDOWN_VIEW_LOADERS": list,
"MARKDOWN_VIEW_LOADER_TEMPLATES_DIR": str,
"MARKDOWN_VIEW_EXTENSIONS": list,
"MARKDOWN_VIEW_BASE_DIR": str,
"MARKDOWN_VIEW_TEMPLATE": str,
"MARKDOWN_VIEW_TEMPLATE_USE_TOC": bool,
"MARKDOWN_VIEW_TEMPLATE_USE_HIGHLIGHT_JS": bool,
"MARKDOWN_VIEW_USE_REQUEST_CONTEXT": bool,
"MARKDOWN_VIEW_EXTRA_CONTEXT": dict
}
Expand Down
3 changes: 3 additions & 0 deletions markdown_view/constants.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
from markdown_view.markdown_extensions import ImageExtension

DEFAULT_MARKDOWN_VIEW_LOADERS = ["markdown_view.loaders.MarkdownLoader", ]
DEFAULT_MARKDOWN_VIEW_LOADER_TEMPLATES_DIR = ""
DEFAULT_MARKDOWN_VIEW_EXTENSIONS = ["tables", "fenced_code", "toc", ImageExtension(), ]
DEFAULT_MARKDOWN_VIEW_TEMPLATE = "markdown_view/markdown.html"
DEFAULT_MARKDOWN_VIEW_TEMPLATE_USE_TOC = True
DEFAULT_MARKDOWN_VIEW_TEMPLATE_USE_HIGHLIGHT_JS = True
DEFAULT_MARKDOWN_VIEW_USE_REQUEST_CONTEXT = False
DEFAULT_MARKDOWN_VIEW_EXTRA_CONTEXT = {}
10 changes: 9 additions & 1 deletion markdown_view/loaders.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
from django.template.utils import get_app_template_dirs
from django.utils._os import safe_join

from markdown_view.constants import DEFAULT_MARKDOWN_VIEW_LOADER_TEMPLATES_DIR


class MarkdownLoader(FilesystemLoader):
"""
Expand All @@ -21,7 +23,13 @@ def get_dirs(self):
"BASE_DIR",
None)
)
dirs = [*get_app_template_dirs('')]
dirs = [*get_app_template_dirs(
getattr(
settings,
"MARKDOWN_VIEW_LOADER_TEMPLATES_DIR",
DEFAULT_MARKDOWN_VIEW_LOADER_TEMPLATES_DIR
)
)]
if base_dir:
dirs.extend([base_dir])
return dirs
Expand Down
36 changes: 21 additions & 15 deletions markdown_view/templates/markdown_view/markdown.html
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.0.2/styles/a11y-light.min.css" integrity="sha256-RrOG8PVkp6JCgJdMUQKbMevN6kuxTOvHJ09rC7snlXQ=" crossorigin="anonymous" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.0.2/highlight.min.js" integrity="sha256-xBWd+VDTBasaTja2bfaCX4aA2H18UxRsjRFkK3rgfkI=" crossorigin="anonymous"></script>
{% if use_highlight_js %}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/a11y-light.min.css" integrity="sha512-PW96n2amVglidqEDLPUdjJ0zByhT20poSqWJYZRutR6CP2QH58k96WmorqNnC4QXnosNeqMJM8FR/93isIifDQ==" crossorigin="anonymous" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha512-lnOllyZZlRk/gQIyjS3+h+LUy54uyM4aGq2zbGc82KTvBlp/fodSpdh/pywPztpU9zUqHcJr+jP+a1zLa9oCJw==" crossorigin="anonymous"></script>
{% endif %}

{% comment %}{{ page_title|safe }}{% endcomment %}

<section>
<h3>Table of Contents</h3>
{{ markdown_toc }}
</section>
{% if use_toc %}
<section id="markdown_view_toc">
<h3>Table of Contents</h3>
{{ markdown_toc }}
</section>
{% endif %}

<section>
<section id="markdown_view_content">
{{ markdown_content }}
</section>

<script>
hljs.initHighlightingOnLoad();
$(document).ready(function(){
$('.md-content div.toc ul').attr("class", "cta-links");
$('.md-content div.toc ul li a').attr("class", "default-fa");
$('.md-content table').attr("class", "table table-bordered table-hover table-striped table-mobile tablesorter tablesorter-default");
});
</script>
{% if use_highlight_js %}
<script>
hljs.initHighlightingOnLoad();
$(document).ready(function(){
$('.md-content div.toc ul').attr("class", "cta-links");
$('.md-content div.toc ul li a').attr("class", "default-fa");
$('.md-content table').attr("class", "table table-bordered table-hover table-striped table-mobile tablesorter tablesorter-default");
});
</script>
{% endif %}
29 changes: 23 additions & 6 deletions markdown_view/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
from django.conf import settings
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.template import Engine, Template, Context
from django.template.loader import render_to_string
from django.utils.safestring import mark_safe
from django.views.generic import TemplateView

from markdown_view.constants import (
DEFAULT_MARKDOWN_VIEW_LOADERS,
DEFAULT_MARKDOWN_VIEW_EXTENSIONS, DEFAULT_MARKDOWN_VIEW_TEMPLATE,
DEFAULT_MARKDOWN_VIEW_USE_REQUEST_CONTEXT, DEFAULT_MARKDOWN_VIEW_EXTRA_CONTEXT,
DEFAULT_MARKDOWN_VIEW_TEMPLATE_USE_HIGHLIGHT_JS, DEFAULT_MARKDOWN_VIEW_TEMPLATE_USE_TOC,
)

logger = logging.getLogger(__name__)
Expand All @@ -36,9 +37,9 @@ def get_context_data(self, *args, **kwargs):
)
render_context_base = {}
if getattr(
settings,
"MARKDOWN_VIEW_USE_REQUEST_CONTEXT",
DEFAULT_MARKDOWN_VIEW_USE_REQUEST_CONTEXT
settings,
"MARKDOWN_VIEW_USE_REQUEST_CONTEXT",
DEFAULT_MARKDOWN_VIEW_USE_REQUEST_CONTEXT
):
render_context_base = context
render_context = Context({
Expand All @@ -51,9 +52,25 @@ def get_context_data(self, *args, **kwargs):
})
context.update({
"markdown_content": mark_safe(template.render(render_context)),
"markdown_toc": mark_safe(md.toc),
"page_title": mark_safe(md.toc_tokens[0]['name']),
"use_highlight_js": getattr(
settings,
"MARKDOWN_VIEW_TEMPLATE_USE_HIGHLIGHT_JS",
DEFAULT_MARKDOWN_VIEW_TEMPLATE_USE_HIGHLIGHT_JS
),
"use_toc": False,
})

if getattr(
settings,
"MARKDOWN_VIEW_TEMPLATE_USE_TOC",
DEFAULT_MARKDOWN_VIEW_TEMPLATE_USE_TOC
):
context.update({
"markdown_toc": mark_safe(md.toc),
"page_title": mark_safe(md.toc_tokens[0]['name']),
"use_toc": True,
})

return context

template_name = getattr(
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
setup(
name='django-markdown-view',
version='0.0.3',
description='Serve .md pages as Django templates.',
description='Serve .md pages as Django views.',
long_description=long_desc,
author='Ryan J. Sullivan',
author_email='ryanj@ryanjsullivan.com',
Expand Down

0 comments on commit 565fe11

Please sign in to comment.