diff --git a/config.json b/config.json index 9acaf807aa1c485346cf1749283d2d77ccfab50b..c4505815c1fce8492a9028b01bc47019be9e4dc0 100644 --- a/config.json +++ b/config.json @@ -8,7 +8,11 @@ "homepage_slug": "index", "static_dir": "theme", "css_file": "main.css", - "default_template": "page.html" + "default_template": "page.html", + "link_target": { + "internal": "_self", + "external": "_blank" + } }, "default_status": "published", "toc_depth": 3, diff --git a/theme/static/css/main.css b/theme/static/css/main.css index 1114568ad820e14ef0f3133738a3780a17b49aab..b55860e89ab874ea1708e02165049c4b40ce1a72 100644 --- a/theme/static/css/main.css +++ b/theme/static/css/main.css @@ -58,6 +58,20 @@ a { a:hover { text-decoration: underline; } +a.external::after { + /* content: '↪'; */ + content: '🡕'; + /*background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20.092'%3E%3Cpath d='m12 0 2.561 2.537-6.975 6.976 2.828 2.828 6.988-6.988L20 7.927 19.998 0H12z'/%3E%3Cpath d='M9 4.092v-2H0v18h18v-9h-2v7H2v-14h7z'/%3E%3C/svg%3E"); + background-repeat: no-repeat no-repeat; + background-position: center center; + background-size: cover;*/ +} +a.external[href^="mailto:"]::after { + content: ''; +} +a.external[href^="mailto:"]::before { + content: '📧'; +} p, blockquote, ul, ol, dl, table, pre { margin: 0 0 1em 0; diff --git a/theme/templates/base.html b/theme/templates/base.html index b798077b55fe0fcfad98567359fb547ebcef5f63..5f51c79999630c110bf9148bc3914936e026158b 100644 --- a/theme/templates/base.html +++ b/theme/templates/base.html @@ -1,9 +1,11 @@ <!DOCTYPE html> {%- import 'macros/getters.html' as get with context -%} +{%- import 'macros/link.html' as link with context -%} {%- import 'macros/cards.html' as cards with context -%} {%- import 'macros/renderers.html' as render with context -%} {%- import 'macros/content_renderer.html' as content_renderer with context -%} +{%- import 'macros/nav.html' as nav with context -%} <html lang="{%- block html_lang -%}{{ l }}{%- endblock html_lang -%}"> <head> @@ -39,28 +41,7 @@ <label for="show-header-menu" class="show-header-menu">☰</label> <input type="checkbox" id="show-header-menu" role="button"> <label for="show-header-menu" class="show-header-menu-bg"> </label> - <nav> - <ul> - {% for item in config.menuitems -%} - {%- if item.tag is defined -%} - {%- call(tagtitle, tagcolor, tagurl, tagpage, tagpages) get.tag_by_name(item.tag, l) -%} - <li style="--category-color: {{ tagcolor }}"><a href="{{ siteurl }}/{{ tagurl }}">{{ tagtitle|e }}</a></li> - {%- endcall -%} - {%- elif item.slug is defined -%} - {%- call(page) get.page_by_slug(item.slug, l) -%} - {%- call(cattitle, catcolor, caturl, catpage, catpages) get.tag_by_name(page.category, l) -%} - <li style="--category-color: {{ catcolor }}"><a href="{{ siteurl }}/{{ page.url }}">{{ page.title|e }}</a></li> - {%- endcall -%} - {%- endcall -%} - {%- else -%} - <br /> - <strong>ERROR: menuitems: Cannot parse item: {{ item|string|e }}</strong><br /> - <br /> - {%- endif -%} - {#- TODO add active class if this is the current site -#} - {%- endfor %} - </ul> - </nav> + {{ nav.render_menu(config.menuitems, l) }} </div> <main> {% block content %} diff --git a/theme/templates/macros/cards.html b/theme/templates/macros/cards.html index 13f78d5c954d54c4a04c8847fb419da4fac7dfc1..a3eb588f284ff1028b2edeafc3d85225ea7bc420 100644 --- a/theme/templates/macros/cards.html +++ b/theme/templates/macros/cards.html @@ -9,13 +9,13 @@ </ul> {%- endmacro -%} -{%- macro card(title, url, catcolor, is_url_external = True) -%} - <li style="--category-color: {{ catcolor }}"><a href="{% if not is_url_external %}{{ siteurl }}/{% endif %}{{ url }}">{{ title|e }}</a></li> +{%- macro card(title, url, catcolor, lang) -%} + <li style="--category-color: {{ catcolor }}">{{ link.render(url, title, lang) }}</li> {%- endmacro -%} {%- macro card_from_page(page, lang) -%} - {%- call(cattitle, catcolor, caturl, catpage, catpages) get.tag_by_name(page.category, l) -%} - {{ card(title=page.title, url=page.url, catcolor=catcolor, is_url_external = False) }} + {%- call(cattitle, catcolor, caturl, catpage, catpages) get.tag_by_name(page.category, lang) -%} + {{ card(title=page.title, url=['slug',page.slug,page.lang]|join(':'), catcolor=catcolor, lang=lang) }} {%- endcall -%} {%- endmacro -%} @@ -25,7 +25,7 @@ {%- endif -%} {%- for page in pages -%} {%- if max == None or loop.index < max -%} - {{ cards.card_from_page(page) }} + {{ cards.card_from_page(page, lang) }} {%- endif -%} {%- endfor -%} {%- if standalone -%} diff --git a/theme/templates/macros/content_renderer.html b/theme/templates/macros/content_renderer.html index 610e05f96bdbda1872189542e470edf2a7d15e48..affdfe572c60d6b02fc77b177af782f83c9b373b 100644 --- a/theme/templates/macros/content_renderer.html +++ b/theme/templates/macros/content_renderer.html @@ -22,7 +22,7 @@ {%- set attr_extra = attr['extra']|d({}) -%} {%- if id %} id="{{ id }}"{%- endif -%} - {%- if classes|length > 0 %} class="{{ classes|join(' ') }}"{%- endif -%} + {%- if classes|length %} class="{{ classes|join(' ') }}"{%- endif -%} {%- for key, value in attr_extra.items() -%} {%- if key not in extra -%} {{ render_attr_extra(key, value, lang) }} @@ -45,16 +45,6 @@ {%- endif -%} {%- endmacro -%} -{%- macro render_link(url, content, lang, attr = None, title = None) -%} - <a {{ render_attr(attr, lang, extra={"href": url, "title": {"value":title, "escape": true}}) }}> - {%- if content is string -%} - {{ content|e }} - {%- else -%} - {{ render_blocks_or_inlines(content, lang) }} - {%- endif -%} - </a> -{%- endmacro -%} - {%- macro render_image(url, alt, lang, attr = None, title = None) -%} <img {{ render_attr(attr, lang, extra={"src": url, "title": {"value":title, "escape": true}}) }} alt=" {%- if alt is string -%} @@ -322,7 +312,7 @@ {%- set content = inline['content'] -%} {%- set url = inline['url'] -%} {%- set title = inline['title'] -%} - {{ render_link(url, content, lang, attr, title) }} + {{ link.render(url, content, lang, attr, title) }} {%- endmacro -%} {%- macro render_inline_image(inline, lang) -%} diff --git a/theme/templates/macros/link.html b/theme/templates/macros/link.html new file mode 100644 index 0000000000000000000000000000000000000000..9526dcb666d7098830aed3f4c2ac251a52cd1fb0 --- /dev/null +++ b/theme/templates/macros/link.html @@ -0,0 +1,77 @@ +{%- import 'macros/content_renderer.html' as content_renderer with context -%} +{%- import 'macros/getters.html' as get with context -%} + +{%- macro render(url, content, lang, attr = None, title = None) -%} + {%- call(parsedurl, anchor, reflang, is_external, reftype, refid, refpage, tagcattitle, tagcatcolor) parse_url(url, lang) -%} + {%- set ns = namespace(relation=None, fullurl=parsedurl) -%} + {%- if anchor -%} + {%- set ns.fullurl = [parsedurl, anchor]|join('#') -%} + {%- endif -%} + {%- if is_external -%} + {%- set ns.relation = "external" -%} + {%- else -%} + {%- set ns.relation = "internal" -%} + {%- endif -%} + {%- set target = config.theme.link_target[ns.relation] -%} + <a {{ content_renderer.render_attr(attr, lang, extra_classes=[ns.relation], extra={"href": ns.fullurl, "title": {"value":title, "escape": true}, "target": target}) }}> + {%- if content is string or content is none -%} + {%- if content is string and content|length -%} + {{ content|e }} + {%- else -%} + {%- if reftype == "tag" -%} + {{ tagcattitle|e }} + {%- else -%} + {{ refpage.title|e }} + {%- endif -%} + {%- endif -%} + {%- else -%} + {{ content_renderer.render_blocks_or_inlines(content, lang) }} + {%- endif -%} + </a> + {%- endcall -%} +{%- endmacro -%} + + +{#- returns: (url, anchor, reflang, is_external, reftype, refid, refpage, tagcattitle, tagcatcolor)-#} +{%- macro parse_url(rawurl, lang) -%} + {%- set urlsplit = rawurl.split('#') -%} + {%- set anchor = urlsplit[1]|d(None) -%} + {%- set urlwoa = urlsplit[0] -%} {#- url without anchor -#} + {%- if not urlwoa|length -%} + {{- caller("", anchor, lang, False, None, None, None, None, None) -}} + {%- else -%} + + {%- set components = urlwoa.split(':') -%} + + {%- if components|length == 1 -%} + {%- set url = ['https://', urlwoa]|join('') -%} + {{- caller(url, anchor, lang, True, None, None, None, None, None) -}} + {%- else -%} + {%- set reftype = components[0] -%} + {%- set refid = components[1] -%} + {%- set reflang = components[2]|d(lang) -%} + {%- set ns = namespace(url=None, page=None, tagtitle=None, tagcolor=None, tagpage=None, catcolor=None, cattitle=None) -%} + {%- if reftype == "slug" -%} + {%- call(page) get.page_by_slug(refid, reflang) -%} + {%- set ns.url = [siteurl, page.url]|join('/') -%} + {%- set ns.page = page -%} + {%- call(cattitle, catcolor, caturl, catpage, catpages) get.tag_by_name(page.category, reflang) -%} + {%- set ns.cattitle = cattitle -%} + {%- set ns.catcolor = catcolor -%} + {%- endcall -%} + {%- endcall -%} + {{- caller(ns.url, anchor, reflang, False, reftype, refid, ns.page, ns.cattitle, ns.catcolor) -}} + {%- elif reftype == "tag" -%} + {%- call(tagtitle, tagcolor, tagurl, tagpage, tagpages) get.tag_by_name(refid, reflang) -%} + {%- set ns.url = [siteurl, tagurl]|join('/') -%} + {%- set ns.tagtitle = tagtitle -%} + {%- set ns.tagcolor = tagcolor -%} + {%- set ns.tagpage = tagpage -%} + {%- endcall -%} + {{- caller(ns.url, anchor, reflang, False, reftype, refid, ns.tagpage, ns.tagtitle, ns.tagcolor) -}} + {%- else -%} + {{- caller(urlwoa, anchor, reflang, True, None, None, None, None, None) -}} + {%- endif -%} + {%- endif -%} + {%- endif -%} +{%- endmacro -%} diff --git a/theme/templates/macros/nav.html b/theme/templates/macros/nav.html new file mode 100644 index 0000000000000000000000000000000000000000..93c77dfefe76f3708e2ab66167eaa508e2e6205a --- /dev/null +++ b/theme/templates/macros/nav.html @@ -0,0 +1,24 @@ +{%- import 'macros/link.html' as link with context -%} + +{%- macro render_menu(items, lang) -%} + <nav> + <ul> + {% for item in items -%} + {{ render_menu_item(item, lang) }} + {%- endfor %} + </ul> + </nav> +{%- endmacro -%} + +{%- macro render_menu_item(item, lang) -%} + {%- if item is string -%} + {%- set url = item -%} + {%- call(parsedurl, anchor, reflang, is_external, reftype, refid, refpage, tagcattitle, tagcatcolor) link.parse_url(url, lang) -%} + <li style="--category-color: {{ tagcatcolor }}"> + {{ link.render(url, None, lang) }} + </li> + {%- endcall -%} + {%- else -%} + TODO: handle custom menu items + {%- endif -%} +{%- endmacro -%} diff --git a/theme/templates/macros/renderers.html b/theme/templates/macros/renderers.html index ea366c2b6072efb80d2262eeecd331ea3cf0d74b..6b7a62c64e6a3defc5b5f62809b9b8f2e78c4758 100644 --- a/theme/templates/macros/renderers.html +++ b/theme/templates/macros/renderers.html @@ -9,7 +9,7 @@ {%- macro section_custom(s, lang) -%} {{ cards.open() }} {%- for c in s.content -%} - {{ cards.card(title=c[lang], url=c.url, catcolor=c.color) }} + {{ cards.card(title=c[lang], url=c.url, catcolor=c.color, lang=lang) }} {%- endfor -%} {{ cards.close() }} {%- endmacro -%}