mirror of
https://github.com/boostorg/website-v2.git
synced 2026-01-19 04:42:17 +00:00
🚧 Markdown renderer
* Stubbed out TemplateView for rendering markdown files * Added a BoostRenderer class to parse the markdown files to support the first iteration of a youtube shortcode and also a Pygments renderer for code blocks. * Added default styles for some common markup so the rendered markdown looks better. The pygments renderer is set to use Solarized Dark right now because that’s the closest I see that matches the design of the site. This can be changed in the class.
This commit is contained in:
5
core/apps.py
Normal file
5
core/apps.py
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class CoreConfig(AppConfig):
|
||||||
|
name = "core"
|
||||||
43
core/boostrenderer.py
Normal file
43
core/boostrenderer.py
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
import re
|
||||||
|
|
||||||
|
from mistletoe import HTMLRenderer
|
||||||
|
from mistletoe.span_token import SpanToken
|
||||||
|
from pygments import highlight
|
||||||
|
from pygments.styles import get_style_by_name as get_style
|
||||||
|
from pygments.lexers import get_lexer_by_name as get_lexer, guess_lexer
|
||||||
|
from pygments.formatters.html import HtmlFormatter
|
||||||
|
|
||||||
|
|
||||||
|
class Youtube(SpanToken):
|
||||||
|
"""
|
||||||
|
Span token for Youtube shortcodes
|
||||||
|
Expected shortcode: `[[ youtube | U4VZ9DRdXAI ]]`
|
||||||
|
youtube is thrown out but in the shortcode for readability
|
||||||
|
"""
|
||||||
|
pattern = re.compile(r"\[\[ *(.+?) *\| *(.+?) *\]\]")
|
||||||
|
|
||||||
|
def __init__(self, match):
|
||||||
|
self.target = match.group(2)
|
||||||
|
|
||||||
|
|
||||||
|
class PygmentsRenderer(HTMLRenderer):
|
||||||
|
formatter = HtmlFormatter()
|
||||||
|
formatter.noclasses = True
|
||||||
|
|
||||||
|
def __init__(self, *extras, style='solarized-dark'):
|
||||||
|
super().__init__(*extras)
|
||||||
|
self.formatter.style = get_style(style)
|
||||||
|
|
||||||
|
def render_block_code(self, token):
|
||||||
|
code = token.children[0].content
|
||||||
|
lexer = get_lexer(token.language) if token.language else guess_lexer(code)
|
||||||
|
return highlight(code, lexer, self.formatter)
|
||||||
|
|
||||||
|
|
||||||
|
class BoostRenderer(PygmentsRenderer):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(Youtube)
|
||||||
|
|
||||||
|
def render_youtube(self, token):
|
||||||
|
template = '<iframe width="560" height="315" src="https://www.youtube.com/embed/{target}" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>'
|
||||||
|
return template.format(target=token.target)
|
||||||
@@ -1,14 +1,15 @@
|
|||||||
import frontmatter
|
import frontmatter
|
||||||
from mistletoe import Document, HTMLRenderer
|
from core.boostrenderer import BoostRenderer
|
||||||
|
from mistletoe import Document
|
||||||
|
|
||||||
|
|
||||||
def process_md():
|
def process_md(filename):
|
||||||
with open("content/test.md") as f:
|
with open(filename) as f:
|
||||||
post = frontmatter.load(f)
|
post = frontmatter.load(f)
|
||||||
metadata = post.metadata
|
metadata = post.metadata
|
||||||
content = post.content
|
content = post.content
|
||||||
|
|
||||||
with HTMLRenderer() as renderer:
|
with BoostRenderer() as renderer:
|
||||||
doc = Document(content)
|
doc = Document(content)
|
||||||
rendered = renderer.render(doc)
|
rendered = renderer.render(doc)
|
||||||
|
|
||||||
|
|||||||
26
core/views.py
Normal file
26
core/views.py
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import os.path
|
||||||
|
|
||||||
|
from django.http import Http404
|
||||||
|
from django.views.generic import TemplateView
|
||||||
|
|
||||||
|
from .markdown import process_md
|
||||||
|
|
||||||
|
|
||||||
|
class MarkdownTemplateView(TemplateView):
|
||||||
|
template_name = "markdown_template.html"
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
filename = self.kwargs.get("title")
|
||||||
|
if not os.path.isfile(f"content/{filename}.md"):
|
||||||
|
raise Http404("Post not found")
|
||||||
|
|
||||||
|
context = self.get_context_data(**kwargs)
|
||||||
|
return self.render_to_response(context)
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
filename = self.kwargs.get("title")
|
||||||
|
metadata, content = process_md(f"content/{filename}.md")
|
||||||
|
context["frontmatter"] = metadata
|
||||||
|
context["content"] = content
|
||||||
|
return context
|
||||||
@@ -2,8 +2,23 @@
|
|||||||
@tailwind components;
|
@tailwind components;
|
||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
|
|
||||||
/* custom classes */
|
|
||||||
|
|
||||||
body {
|
body {
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@layer base {
|
||||||
|
h1 {
|
||||||
|
@apply text-6xl;
|
||||||
|
@apply mb-3;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
@apply text-4xl;
|
||||||
|
@apply my-5;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
@apply py-5;
|
||||||
|
}
|
||||||
|
pre {
|
||||||
|
@apply p-6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -554,6 +554,24 @@ select {
|
|||||||
outline: 1px solid ButtonText;
|
outline: 1px solid ButtonText;
|
||||||
outline: 1px auto -webkit-focus-ring-color;
|
outline: 1px auto -webkit-focus-ring-color;
|
||||||
}
|
}
|
||||||
|
h1 {
|
||||||
|
font-size: 3.75rem;
|
||||||
|
line-height: 1;
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
font-size: 2.25rem;
|
||||||
|
line-height: 2.5rem;
|
||||||
|
margin-top: 1.25rem;
|
||||||
|
margin-bottom: 1.25rem;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
padding-top: 1.25rem;
|
||||||
|
padding-bottom: 1.25rem;
|
||||||
|
}
|
||||||
|
pre {
|
||||||
|
padding: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
*, ::before, ::after {
|
*, ::before, ::after {
|
||||||
--tw-translate-x: 0;
|
--tw-translate-x: 0;
|
||||||
@@ -669,12 +687,6 @@ select {
|
|||||||
.left-0 {
|
.left-0 {
|
||||||
left: 0px;
|
left: 0px;
|
||||||
}
|
}
|
||||||
.right-0 {
|
|
||||||
right: 0px;
|
|
||||||
}
|
|
||||||
.right-4 {
|
|
||||||
right: 1rem;
|
|
||||||
}
|
|
||||||
.right-3 {
|
.right-3 {
|
||||||
right: 0.75rem;
|
right: 0.75rem;
|
||||||
}
|
}
|
||||||
@@ -725,10 +737,6 @@ select {
|
|||||||
margin-left: 0.75rem;
|
margin-left: 0.75rem;
|
||||||
margin-right: 0.75rem;
|
margin-right: 0.75rem;
|
||||||
}
|
}
|
||||||
.my-11 {
|
|
||||||
margin-top: 2.75rem;
|
|
||||||
margin-bottom: 2.75rem;
|
|
||||||
}
|
|
||||||
.my-6 {
|
.my-6 {
|
||||||
margin-top: 1.5rem;
|
margin-top: 1.5rem;
|
||||||
margin-bottom: 1.5rem;
|
margin-bottom: 1.5rem;
|
||||||
@@ -787,21 +795,18 @@ select {
|
|||||||
.mb-16 {
|
.mb-16 {
|
||||||
margin-bottom: 4rem;
|
margin-bottom: 4rem;
|
||||||
}
|
}
|
||||||
.mt-11 {
|
|
||||||
margin-top: 2.75rem;
|
|
||||||
}
|
|
||||||
.mb-1 {
|
.mb-1 {
|
||||||
margin-bottom: 0.25rem;
|
margin-bottom: 0.25rem;
|
||||||
}
|
}
|
||||||
.mb-5 {
|
.mt-11 {
|
||||||
margin-bottom: 1.25rem;
|
margin-top: 2.75rem;
|
||||||
}
|
|
||||||
.mr-2 {
|
|
||||||
margin-right: 0.5rem;
|
|
||||||
}
|
}
|
||||||
.mr-1 {
|
.mr-1 {
|
||||||
margin-right: 0.25rem;
|
margin-right: 0.25rem;
|
||||||
}
|
}
|
||||||
|
.mb-5 {
|
||||||
|
margin-bottom: 1.25rem;
|
||||||
|
}
|
||||||
.block {
|
.block {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
@@ -948,26 +953,16 @@ select {
|
|||||||
margin-top: calc(0.75rem * calc(1 - var(--tw-space-y-reverse)));
|
margin-top: calc(0.75rem * calc(1 - var(--tw-space-y-reverse)));
|
||||||
margin-bottom: calc(0.75rem * var(--tw-space-y-reverse));
|
margin-bottom: calc(0.75rem * var(--tw-space-y-reverse));
|
||||||
}
|
}
|
||||||
.space-x-11 > :not([hidden]) ~ :not([hidden]) {
|
.space-y-11 > :not([hidden]) ~ :not([hidden]) {
|
||||||
--tw-space-x-reverse: 0;
|
--tw-space-y-reverse: 0;
|
||||||
margin-right: calc(2.75rem * var(--tw-space-x-reverse));
|
margin-top: calc(2.75rem * calc(1 - var(--tw-space-y-reverse)));
|
||||||
margin-left: calc(2.75rem * calc(1 - var(--tw-space-x-reverse)));
|
margin-bottom: calc(2.75rem * var(--tw-space-y-reverse));
|
||||||
}
|
|
||||||
.space-x-6 > :not([hidden]) ~ :not([hidden]) {
|
|
||||||
--tw-space-x-reverse: 0;
|
|
||||||
margin-right: calc(1.5rem * var(--tw-space-x-reverse));
|
|
||||||
margin-left: calc(1.5rem * calc(1 - var(--tw-space-x-reverse)));
|
|
||||||
}
|
}
|
||||||
.space-y-6 > :not([hidden]) ~ :not([hidden]) {
|
.space-y-6 > :not([hidden]) ~ :not([hidden]) {
|
||||||
--tw-space-y-reverse: 0;
|
--tw-space-y-reverse: 0;
|
||||||
margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));
|
margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));
|
||||||
margin-bottom: calc(1.5rem * var(--tw-space-y-reverse));
|
margin-bottom: calc(1.5rem * var(--tw-space-y-reverse));
|
||||||
}
|
}
|
||||||
.space-y-11 > :not([hidden]) ~ :not([hidden]) {
|
|
||||||
--tw-space-y-reverse: 0;
|
|
||||||
margin-top: calc(2.75rem * calc(1 - var(--tw-space-y-reverse)));
|
|
||||||
margin-bottom: calc(2.75rem * var(--tw-space-y-reverse));
|
|
||||||
}
|
|
||||||
.divide-y > :not([hidden]) ~ :not([hidden]) {
|
.divide-y > :not([hidden]) ~ :not([hidden]) {
|
||||||
--tw-divide-y-reverse: 0;
|
--tw-divide-y-reverse: 0;
|
||||||
border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse)));
|
border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse)));
|
||||||
@@ -1083,9 +1078,9 @@ select {
|
|||||||
padding-top: 2.75rem;
|
padding-top: 2.75rem;
|
||||||
padding-bottom: 2.75rem;
|
padding-bottom: 2.75rem;
|
||||||
}
|
}
|
||||||
.py-16 {
|
.py-0 {
|
||||||
padding-top: 4rem;
|
padding-top: 0px;
|
||||||
padding-bottom: 4rem;
|
padding-bottom: 0px;
|
||||||
}
|
}
|
||||||
.px-5 {
|
.px-5 {
|
||||||
padding-left: 1.25rem;
|
padding-left: 1.25rem;
|
||||||
@@ -1111,9 +1106,9 @@ select {
|
|||||||
padding-left: 1.5rem;
|
padding-left: 1.5rem;
|
||||||
padding-right: 1.5rem;
|
padding-right: 1.5rem;
|
||||||
}
|
}
|
||||||
.py-0 {
|
.py-16 {
|
||||||
padding-top: 0px;
|
padding-top: 4rem;
|
||||||
padding-bottom: 0px;
|
padding-bottom: 4rem;
|
||||||
}
|
}
|
||||||
.pr-2 {
|
.pr-2 {
|
||||||
padding-right: 0.5rem;
|
padding-right: 0.5rem;
|
||||||
@@ -1169,18 +1164,12 @@ select {
|
|||||||
.pr-11 {
|
.pr-11 {
|
||||||
padding-right: 2.75rem;
|
padding-right: 2.75rem;
|
||||||
}
|
}
|
||||||
.pb-4 {
|
|
||||||
padding-bottom: 1rem;
|
|
||||||
}
|
|
||||||
.text-left {
|
.text-left {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
.text-center {
|
.text-center {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
.align-middle {
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
.font-cairo {
|
.font-cairo {
|
||||||
font-family: 'Cairo', sans-serif;
|
font-family: 'Cairo', sans-serif;
|
||||||
}
|
}
|
||||||
@@ -1266,8 +1255,6 @@ select {
|
|||||||
transition-timing-function: cubic-bezier(0.4, 0, 1, 1);
|
transition-timing-function: cubic-bezier(0.4, 0, 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* custom classes */
|
|
||||||
|
|
||||||
body {
|
body {
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
@@ -1281,21 +1268,11 @@ body {
|
|||||||
background-color: rgb(255 159 0 / var(--tw-bg-opacity));
|
background-color: rgb(255 159 0 / var(--tw-bg-opacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
.checked\:text-orange:checked {
|
|
||||||
--tw-text-opacity: 1;
|
|
||||||
color: rgb(255 159 0 / var(--tw-text-opacity));
|
|
||||||
}
|
|
||||||
|
|
||||||
.hover\:bg-orange:hover {
|
.hover\:bg-orange:hover {
|
||||||
--tw-bg-opacity: 1;
|
--tw-bg-opacity: 1;
|
||||||
background-color: rgb(255 159 0 / var(--tw-bg-opacity));
|
background-color: rgb(255 159 0 / var(--tw-bg-opacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
.focus\:bg-orange:focus {
|
|
||||||
--tw-bg-opacity: 1;
|
|
||||||
background-color: rgb(255 159 0 / var(--tw-bg-opacity));
|
|
||||||
}
|
|
||||||
|
|
||||||
.focus\:text-charcoal:focus {
|
.focus\:text-charcoal:focus {
|
||||||
--tw-text-opacity: 1;
|
--tw-text-opacity: 1;
|
||||||
color: rgb(23 42 52 / var(--tw-text-opacity));
|
color: rgb(23 42 52 / var(--tw-text-opacity));
|
||||||
@@ -1372,47 +1349,11 @@ body {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sm\:space-y-4 > :not([hidden]) ~ :not([hidden]) {
|
|
||||||
--tw-space-y-reverse: 0;
|
|
||||||
margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse)));
|
|
||||||
margin-bottom: calc(1rem * var(--tw-space-y-reverse));
|
|
||||||
}
|
|
||||||
|
|
||||||
.sm\:space-y-3 > :not([hidden]) ~ :not([hidden]) {
|
|
||||||
--tw-space-y-reverse: 0;
|
|
||||||
margin-top: calc(0.75rem * calc(1 - var(--tw-space-y-reverse)));
|
|
||||||
margin-bottom: calc(0.75rem * var(--tw-space-y-reverse));
|
|
||||||
}
|
|
||||||
|
|
||||||
.sm\:px-6 {
|
.sm\:px-6 {
|
||||||
padding-left: 1.5rem;
|
padding-left: 1.5rem;
|
||||||
padding-right: 1.5rem;
|
padding-right: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sm\:py-4 {
|
|
||||||
padding-top: 1rem;
|
|
||||||
padding-bottom: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sm\:py-11 {
|
|
||||||
padding-top: 2.75rem;
|
|
||||||
padding-bottom: 2.75rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sm\:py-6 {
|
|
||||||
padding-top: 1.5rem;
|
|
||||||
padding-bottom: 1.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sm\:px-3 {
|
|
||||||
padding-left: 0.75rem;
|
|
||||||
padding-right: 0.75rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sm\:pt-4 {
|
|
||||||
padding-top: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sm\:text-5xl {
|
.sm\:text-5xl {
|
||||||
font-size: 3rem;
|
font-size: 3rem;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
@@ -1440,6 +1381,11 @@ body {
|
|||||||
margin-bottom: 0px;
|
margin-bottom: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.md\:my-6 {
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
.md\:mx-0 {
|
.md\:mx-0 {
|
||||||
margin-left: 0px;
|
margin-left: 0px;
|
||||||
margin-right: 0px;
|
margin-right: 0px;
|
||||||
@@ -1450,11 +1396,6 @@ body {
|
|||||||
margin-bottom: 2.75rem;
|
margin-bottom: 2.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.md\:my-6 {
|
|
||||||
margin-top: 1.5rem;
|
|
||||||
margin-bottom: 1.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.md\:mb-11 {
|
.md\:mb-11 {
|
||||||
margin-bottom: 2.75rem;
|
margin-bottom: 2.75rem;
|
||||||
}
|
}
|
||||||
@@ -1467,20 +1408,20 @@ body {
|
|||||||
margin-top: 2rem;
|
margin-top: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.md\:mr-11 {
|
.md\:mb-0 {
|
||||||
margin-right: 2.75rem;
|
margin-bottom: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.md\:mt-0 {
|
.md\:mr-11 {
|
||||||
margin-top: 0px;
|
margin-right: 2.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.md\:mt-11 {
|
.md\:mt-11 {
|
||||||
margin-top: 2.75rem;
|
margin-top: 2.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.md\:mb-0 {
|
.md\:mt-0 {
|
||||||
margin-bottom: 0px;
|
margin-top: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.md\:mb-6 {
|
.md\:mb-6 {
|
||||||
@@ -1519,10 +1460,6 @@ body {
|
|||||||
width: 25%;
|
width: 25%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.md\:w-full {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.md\:w-1\/3 {
|
.md\:w-1\/3 {
|
||||||
width: 33.333333%;
|
width: 33.333333%;
|
||||||
}
|
}
|
||||||
@@ -1531,10 +1468,6 @@ body {
|
|||||||
width: auto;
|
width: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.md\:w-2\/3 {
|
|
||||||
width: 66.666667%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.md\:max-w-7xl {
|
.md\:max-w-7xl {
|
||||||
max-width: 80rem;
|
max-width: 80rem;
|
||||||
}
|
}
|
||||||
@@ -1650,6 +1583,16 @@ body {
|
|||||||
padding-right: 2.5rem;
|
padding-right: 2.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.md\:py-6 {
|
||||||
|
padding-top: 1.5rem;
|
||||||
|
padding-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md\:px-0 {
|
||||||
|
padding-left: 0px;
|
||||||
|
padding-right: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
.md\:py-3 {
|
.md\:py-3 {
|
||||||
padding-top: 0.75rem;
|
padding-top: 0.75rem;
|
||||||
padding-bottom: 0.75rem;
|
padding-bottom: 0.75rem;
|
||||||
@@ -1660,11 +1603,6 @@ body {
|
|||||||
padding-right: 2rem;
|
padding-right: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.md\:px-0 {
|
|
||||||
padding-left: 0px;
|
|
||||||
padding-right: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.md\:py-11 {
|
.md\:py-11 {
|
||||||
padding-top: 2.75rem;
|
padding-top: 2.75rem;
|
||||||
padding-bottom: 2.75rem;
|
padding-bottom: 2.75rem;
|
||||||
@@ -1675,16 +1613,6 @@ body {
|
|||||||
padding-bottom: 0px;
|
padding-bottom: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.md\:py-16 {
|
|
||||||
padding-top: 4rem;
|
|
||||||
padding-bottom: 4rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.md\:py-6 {
|
|
||||||
padding-top: 1.5rem;
|
|
||||||
padding-bottom: 1.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.md\:pl-6 {
|
.md\:pl-6 {
|
||||||
padding-left: 1.5rem;
|
padding-left: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,9 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="description" content="{% block description %}{% endblock %}">
|
||||||
|
<meta name="keywords" content="{% block keywords %}{% endblock %}">
|
||||||
|
<meta name="author" content="{% block author %}{% endblock %}">
|
||||||
<link href="{% static 'css/styles.css' %}" rel="stylesheet">
|
<link href="{% static 'css/styles.css' %}" rel="stylesheet">
|
||||||
<!-- Google fonts for Cairo Medium and SemiBold -->
|
<!-- Google fonts for Cairo Medium and SemiBold -->
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
|||||||
18
templates/markdown_template.html
Normal file
18
templates/markdown_template.html
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% load static %}
|
||||||
|
|
||||||
|
{% block title %}{{ frontmatter.title }}{% endblock %}
|
||||||
|
{% block description %}{{ frontmatter.description }}{% endblock %}
|
||||||
|
{% block keywords %}{{ frontmatter.keywords }}{% endblock %}
|
||||||
|
{% block author %}{{ frontmatter.author }}{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="py-0 md:py-6 mb-3 px-3 md:px-0">
|
||||||
|
|
||||||
|
<div class="mb-6 md:mb-0">
|
||||||
|
{{ content|safe }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
Reference in New Issue
Block a user