From a2ea06d513a5802964f8f0ef5795cec7e548ed7b Mon Sep 17 00:00:00 2001 From: Alejandro Soto Date: Sat, 13 Sep 2025 14:55:15 -0600 Subject: Squashed 'themes/tabi-lean/' content from commit 95c8796 git-subtree-dir: themes/tabi-lean git-subtree-split: 95c879696445ede40daa7a30a88dae5dd74d5c0c --- templates/404.html | 34 +++ templates/anchor-link.html | 1 + templates/archive.html | 89 ++++++ templates/atom.xml | 110 +++++++ templates/base.html | 51 ++++ templates/cards.html | 32 +++ templates/index.html | 1 + templates/info-page.html | 21 ++ templates/internal/alias.html | 13 + templates/macros/feed_utils.html | 17 ++ templates/macros/format_date.html | 59 ++++ templates/macros/list_posts.html | 163 +++++++++++ templates/macros/page_header.html | 18 ++ templates/macros/rel_attributes.html | 19 ++ templates/macros/series_page.html | 162 +++++++++++ templates/macros/settings.html | 68 +++++ templates/macros/table_of_contents.html | 54 ++++ templates/macros/target_attribute.html | 11 + templates/macros/translate.html | 72 +++++ templates/page.html | 368 ++++++++++++++++++++++++ templates/partials/analytics.html | 38 +++ templates/partials/cards_pages.html | 46 +++ templates/partials/comments.html | 95 ++++++ templates/partials/content_security_policy.html | 119 ++++++++ templates/partials/copyright.html | 39 +++ templates/partials/extra_features.html | 88 ++++++ templates/partials/filter_card_tags.html | 35 +++ templates/partials/footer.html | 127 ++++++++ templates/partials/hcard.html | 75 +++++ templates/partials/hcard_small.html | 26 ++ templates/partials/header.html | 182 ++++++++++++ templates/partials/history_url.html | 26 ++ templates/partials/home_banner.html | 20 ++ templates/partials/iine_button.html | 33 +++ templates/partials/language_switcher.html | 38 +++ templates/partials/main_page_posts_list.html | 61 ++++ templates/partials/main_page_projects_list.html | 16 ++ templates/partials/multilingual_tags.html | 29 ++ templates/partials/nav.html | 60 ++++ templates/partials/paginate.html | 27 ++ templates/partials/search_modal.html | 31 ++ templates/partials/social_media_images.html | 50 ++++ templates/partials/theme_switcher.html | 31 ++ templates/partials/title.html | 40 +++ templates/partials/webmentions.html | 51 ++++ templates/section.html | 57 ++++ templates/series.html | 62 ++++ templates/shortcodes/add_src_to_code_block.html | 1 + templates/shortcodes/admonition.html | 12 + templates/shortcodes/aside.html | 5 + templates/shortcodes/dimmable_image.html | 31 ++ templates/shortcodes/dual_theme_image.html | 45 +++ templates/shortcodes/force_text_direction.html | 5 + templates/shortcodes/full_width_image.html | 22 ++ templates/shortcodes/iine.html | 5 + templates/shortcodes/image_hover.html | 50 ++++ templates/shortcodes/image_toggler.html | 57 ++++ templates/shortcodes/invertible_image.html | 32 +++ templates/shortcodes/mermaid.html | 8 + templates/shortcodes/multilingual_quote.html | 37 +++ templates/shortcodes/references.html | 3 + templates/shortcodes/remote_text.html | 30 ++ templates/shortcodes/spoiler.html | 13 + templates/shortcodes/toc.html | 2 + templates/shortcodes/wide_container.html | 3 + templates/sitemap.xml | 12 + templates/tags/list.html | 40 +++ templates/tags/single.html | 22 ++ templates/taxonomy_list.html | 40 +++ templates/taxonomy_single.html | 22 ++ 70 files changed, 3362 insertions(+) create mode 100644 templates/404.html create mode 100644 templates/anchor-link.html create mode 100644 templates/archive.html create mode 100644 templates/atom.xml create mode 100644 templates/base.html create mode 100644 templates/cards.html create mode 100644 templates/index.html create mode 100644 templates/info-page.html create mode 100644 templates/internal/alias.html create mode 100644 templates/macros/feed_utils.html create mode 100644 templates/macros/format_date.html create mode 100644 templates/macros/list_posts.html create mode 100644 templates/macros/page_header.html create mode 100644 templates/macros/rel_attributes.html create mode 100644 templates/macros/series_page.html create mode 100644 templates/macros/settings.html create mode 100644 templates/macros/table_of_contents.html create mode 100644 templates/macros/target_attribute.html create mode 100644 templates/macros/translate.html create mode 100644 templates/page.html create mode 100644 templates/partials/analytics.html create mode 100644 templates/partials/cards_pages.html create mode 100644 templates/partials/comments.html create mode 100644 templates/partials/content_security_policy.html create mode 100644 templates/partials/copyright.html create mode 100644 templates/partials/extra_features.html create mode 100644 templates/partials/filter_card_tags.html create mode 100644 templates/partials/footer.html create mode 100644 templates/partials/hcard.html create mode 100644 templates/partials/hcard_small.html create mode 100644 templates/partials/header.html create mode 100644 templates/partials/history_url.html create mode 100644 templates/partials/home_banner.html create mode 100644 templates/partials/iine_button.html create mode 100644 templates/partials/language_switcher.html create mode 100644 templates/partials/main_page_posts_list.html create mode 100644 templates/partials/main_page_projects_list.html create mode 100644 templates/partials/multilingual_tags.html create mode 100644 templates/partials/nav.html create mode 100644 templates/partials/paginate.html create mode 100644 templates/partials/search_modal.html create mode 100644 templates/partials/social_media_images.html create mode 100644 templates/partials/theme_switcher.html create mode 100644 templates/partials/title.html create mode 100644 templates/partials/webmentions.html create mode 100644 templates/section.html create mode 100644 templates/series.html create mode 100644 templates/shortcodes/add_src_to_code_block.html create mode 100644 templates/shortcodes/admonition.html create mode 100644 templates/shortcodes/aside.html create mode 100644 templates/shortcodes/dimmable_image.html create mode 100644 templates/shortcodes/dual_theme_image.html create mode 100644 templates/shortcodes/force_text_direction.html create mode 100644 templates/shortcodes/full_width_image.html create mode 100644 templates/shortcodes/iine.html create mode 100644 templates/shortcodes/image_hover.html create mode 100644 templates/shortcodes/image_toggler.html create mode 100644 templates/shortcodes/invertible_image.html create mode 100644 templates/shortcodes/mermaid.html create mode 100644 templates/shortcodes/multilingual_quote.html create mode 100644 templates/shortcodes/references.html create mode 100644 templates/shortcodes/remote_text.html create mode 100644 templates/shortcodes/spoiler.html create mode 100644 templates/shortcodes/toc.html create mode 100644 templates/shortcodes/wide_container.html create mode 100644 templates/sitemap.xml create mode 100644 templates/tags/list.html create mode 100644 templates/tags/single.html create mode 100644 templates/taxonomy_list.html create mode 100644 templates/taxonomy_single.html (limited to 'templates') diff --git a/templates/404.html b/templates/404.html new file mode 100644 index 0000000..4c19dac --- /dev/null +++ b/templates/404.html @@ -0,0 +1,34 @@ +{% extends "page.html" %} + +{% macro display_404_message(language_name) %} + {%- set language_strings = load_data(path="i18n/" ~ language_name ~ '.toml', required=false) -%} + {%- if not language_strings -%} + {%- set language_strings = load_data(path="themes/tabi/i18n/" ~ language_name ~ '.toml', required=false) -%} + {%- endif -%} +

{{ macros_translate::translate(key="page_missing", default="The page you've requested seems to be missing", force_lang=language_name, language_strings=language_strings) }} + {%- if config.languages | length > 0 -%} +  {{ macros_translate::translate(key="translation_missing", default="or hasn't been translated into your language yet", force_lang=language_name, language_strings=language_strings) }}{{ macros_translate::translate(key="full_stop", default=".", force_lang=language_name, language_strings=language_strings) }} + {%- else %}. + {%- endif %}
+ {{ macros_translate::translate(key="check_url", default="Check the URL for errors or", force_lang=language_name, language_strings=language_strings) }} + + {{ macros_translate::translate(key="go_home", default="go back to the homepage", force_lang=language_name, language_strings=language_strings) }}{{ macros_translate::translate(key="full_stop", default=".", force_lang=language_name, language_strings=language_strings) }}

+{% endmacro %} + +{% block main_content %} +
+ {{ macros_page_header::page_header(title="404")}} +
{{ macros_translate::translate(key="not_found") }}
+ + {# 404 message for base language #} + {{ self::display_404_message(language_name=config.default_language, is_multilingual=is_multilingual) }} + + {#- Iterate through each extra language, to display the localised 404 message -#} + {%- for language_name, language in config.languages -%} + {%- if language_name == config.default_language -%} + {%- continue -%} {#- We've already displayed the 404 message for the base language -#} + {%- endif -%} + {{ self::display_404_message(language_name=language_name, is_multilingual=is_multilingual) }} + {%- endfor -%} +
+{% endblock main_content %} diff --git a/templates/anchor-link.html b/templates/anchor-link.html new file mode 100644 index 0000000..254dbe3 --- /dev/null +++ b/templates/anchor-link.html @@ -0,0 +1 @@ + diff --git a/templates/archive.html b/templates/archive.html new file mode 100644 index 0000000..637b414 --- /dev/null +++ b/templates/archive.html @@ -0,0 +1,89 @@ +{% extends "base.html" %} + +{% block main_content %} + +{{ macros_page_header::page_header(title=section.title) }} + +{# Set locale for date #} +{% set date_locale = macros_translate::translate(key="date_locale", default="en_GB", language_strings=language_strings) %} + +{#- Check for language-specific date formats -#} +{%- set language_format = "" -%} +{%- if config.extra.date_formats -%} + {%- for format_config in config.extra.date_formats -%} + {%- if format_config.lang == lang -%} + {%- if format_config.archive -%} + {%- set_global language_format = format_config.archive -%} + {%- endif -%} + {%- endif -%} + {%- endfor -%} +{%- endif -%} + +
+ +
+ +{% endblock main_content %} diff --git a/templates/atom.xml b/templates/atom.xml new file mode 100644 index 0000000..3e5b55c --- /dev/null +++ b/templates/atom.xml @@ -0,0 +1,110 @@ +{%- import "macros/translate.html" as macros_translate -%} +{%- import "macros/settings.html" as macros_settings -%} +{#- Load the internationalisation data -#} +{%- set language_strings = load_data(path="i18n/" ~ lang ~ '.toml', required=false) -%} +{%- if not language_strings -%} + {%- set language_strings = load_data(path="themes/tabi/i18n/" ~ lang ~ ".toml", required=false) -%} +{%- endif -%} + + + + + {{ config.base_url }} + + {{ config.extra.separator | default(value="•") }} + + + {{- macros_translate::translate(key="about_feeds", default="This is a web feed, also known as an Atom feed. Subscribe by copying the URL from the address bar into your newsreader", language_strings=language_strings) -}} + + + {{- macros_translate::translate(key="visit_the_site", default="Visit website", language_strings=language_strings) -}} + + + {{- macros_translate::translate(key="recent_posts", default="Recent posts", language_strings=language_strings) -}} + + + {{- macros_translate::translate(key="last_updated_on", default="Updated on $DATE", language_strings=language_strings) -}} + + + {{- config.extra.default_theme | default(value="") -}} + + + {{- config.extra.post_listing_date | default(value="date") -}} + + + {%- if term -%} + {{ term.name }} + {%- elif section.title -%} + {{ section.title }} + {%- else -%} + {{ config.title }} + {%- endif -%} + + + + {#- Load extra CSS (skin) if set in config.toml -#} + {%- if config.extra.skin -%} + + {%- endif -%} + + {{ config.title | striptags | safe }} + {%- if term %} - {{ term.name }} + {%- elif section.title %} - {{ section.title }} + {%- endif -%} + + {%- if config.description %} + {{ config.description }} + {%- endif %} + + + Zola + {%- if last_updated -%} + {{ last_updated | date(format="%+") }} + {%- endif -%} + {{ feed_url | safe }} + {%- for page in pages %} + {%- if macros_settings::evaluate_setting_priority(setting="hide_from_feed", page=page, default_global_value=false) == "true" -%} + {%- continue -%} + {%- endif -%} + {#- Skip if hide_from_main_feed is true and this is the main feed -#} + {%- if macros_settings::evaluate_setting_priority(setting="hide_from_main_feed", page=page, default_global_value=false) == "true" + and not section + and not term -%} + {%- continue -%} + {%- endif -%} + + {{ page.title }} + {{ page.date | date(format="%+") }} + {{ page.updated | default(value=page.date) | date(format="%+") }} + + + {%- if page.authors -%} + {{ page.authors[0] }} + {%- elif config.author -%} + {{ config.author }} + {%- else -%} + Unknown + {%- endif -%} + + + + {{ page.permalink | safe }} + {% if config.extra.full_content_in_feed %} + {{ page.content }} + {% endif -%} + {% if page.description -%} + {{ page.description }} + {% elif page.summary -%} + {{ page.summary | striptags | trim_end_matches(pat=".") | safe }}… + {% endif -%} + + {%- endfor %} + diff --git a/templates/base.html b/templates/base.html new file mode 100644 index 0000000..56f2a65 --- /dev/null +++ b/templates/base.html @@ -0,0 +1,51 @@ +{% import "macros/feed_utils.html" as feed_utils %} +{% import "macros/format_date.html" as macros_format_date %} +{% import "macros/list_posts.html" as macros_list_posts %} +{% import "macros/page_header.html" as macros_page_header %} +{% import "macros/rel_attributes.html" as macros_rel_attributes %} +{% import "macros/series_page.html" as macros_series_page %} +{% import "macros/settings.html" as macros_settings %} +{% import "macros/table_of_contents.html" as macros_toc %} +{% import "macros/target_attribute.html" as macros_target_attribute %} +{% import "macros/translate.html" as macros_translate %} + +{# Load the internationalisation data for the current language from +the .toml files in the user's '/i18n' folder, falling back to the theme's. +This variable will hold all the text strings for the language #} +{%- set language_strings = load_data(path="i18n/" ~ lang ~ '.toml', required=false) -%} +{%- if not language_strings -%} + {%- set language_strings = load_data(path="themes/tabi/i18n/" ~ lang ~ ".toml", required=false) -%} +{%- endif -%} +{% set rtl_languages = ["ar", "arc", "az", "dv", "ff", "he", "ku", "nqo", "fa", "rhg", "syc", "ur"] %} + +{#- Necessary for the hierarchy macro -#} +{%- if page -%} + {%- set current_page = page -%} +{%- else -%} + {%- set current_page = ""-%} +{%- endif -%} + + + + +{% include "partials/header.html" %} + + + {% include "partials/nav.html" %} +
+ + {# Post page is the default #} + {% block main_content %} + Nothing here?! + {% endblock main_content %} +
+ {% include "partials/footer.html" %} + + {# Users can optionally provide this template to add content to the body element. #} + {% include "tabi/extend_body.html" ignore missing %} + + + diff --git a/templates/cards.html b/templates/cards.html new file mode 100644 index 0000000..451f6b2 --- /dev/null +++ b/templates/cards.html @@ -0,0 +1,32 @@ +{% extends "base.html" %} + +{% block main_content %} + {% if section.extra.section_path -%} + {% set section = get_section(path=section.extra.section_path) %} + {% endif -%} + + {{ macros_page_header::page_header(title=section.title) }} + +
+ {% if section.content -%} +
{{ section.content | safe }}
+ {% endif %} + + {%- if paginator %} + {%- set show_pages = paginator.pages -%} + {% else %} + {%- set show_pages = section.pages -%} + {% endif -%} + + {%- if macros_settings::evaluate_setting_priority(setting="enable_cards_tag_filtering", page=section, default_global_value=true) == "true" -%} + {%- include "partials/filter_card_tags.html" -%} + {%- endif -%} + + + {%- include "partials/cards_pages.html" -%} +
+ + {% if paginator %} + {%- include "partials/paginate.html" -%} + {% endif %} +{% endblock main_content %} diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..d0dfc01 --- /dev/null +++ b/templates/index.html @@ -0,0 +1 @@ +{% extends "section.html" %} diff --git a/templates/info-page.html b/templates/info-page.html new file mode 100644 index 0000000..077b1a1 --- /dev/null +++ b/templates/info-page.html @@ -0,0 +1,21 @@ +{# Template for non-articles (About Me, Privacy…) #} + +{% extends "base.html" %} + +{%- block main_content %} + +{%- set page_or_section = page | default(value=section) -%} + +{{ macros_page_header::page_header(title=page_or_section.title) }} + +
+
+ {# The replace pattern is used to enable arbitrary locations for the Table of Contents #} + {# This is Philipp Oppermann's workaround: https://github.com/getzola/zola/issues/584#issuecomment-474329637 #} + {{ page_or_section.content | replace(from="", to=macros_toc::toc(page=page_or_section, header=false, language_strings=language_strings)) | safe }} +
+
+ +{%- include "partials/extra_features.html" -%} + +{%- endblock main_content %} diff --git a/templates/internal/alias.html b/templates/internal/alias.html new file mode 100644 index 0000000..f56f769 --- /dev/null +++ b/templates/internal/alias.html @@ -0,0 +1,13 @@ + + + + + + + + Redirect + + +

Click here to be redirected.

+ + diff --git a/templates/macros/feed_utils.html b/templates/macros/feed_utils.html new file mode 100644 index 0000000..ff35194 --- /dev/null +++ b/templates/macros/feed_utils.html @@ -0,0 +1,17 @@ +{#- Feed utility macros -#} + +{#- Zola 0.19.0 uses `generate_feeds`. Prior versions use `generate_feed` -#} +{%- macro get_generate_feed() -%} + {{- config.generate_feeds | default(value=config.generate_feed) -}} +{%- endmacro get_generate_feed -%} + +{%- macro get_feed_url() -%} + {{- config.feed_filenames[0] | default(value=(config.feed_filename)) -}} +{%- endmacro get_feed_url -%} + +{#- Check footer feed icon conditions -#} +{%- macro should_show_footer_feed_icon() -%} + {%- set generate_feed = feed_utils::get_generate_feed() == "true" -%} + {%- set feed_url = feed_utils::get_feed_url() -%} + {{- generate_feed and config.extra.feed_icon and feed_url -}} +{%- endmacro should_show_footer_feed_icon -%} diff --git a/templates/macros/format_date.html b/templates/macros/format_date.html new file mode 100644 index 0000000..f747fd1 --- /dev/null +++ b/templates/macros/format_date.html @@ -0,0 +1,59 @@ +{%- macro format_date(date, short, language_strings="") -%} + +{#- Set locale -#} +{%- set date_locale = macros_translate::translate(key="date_locale", default="en_GB", language_strings=language_strings) -%} + +{#- Check for language-specific date formats -#} +{%- set language_format = "" -%} +{%- if config.extra.date_formats -%} + {%- for format_config in config.extra.date_formats -%} + {%- if format_config.lang == lang -%} + {%- if short and format_config.short -%} + {%- set_global language_format = format_config.short -%} + {%- elif not short and format_config.long -%} + {%- set_global language_format = format_config.long -%} + {%- endif -%} + {%- endif -%} + {%- endfor -%} +{%- endif -%} + +{%- if language_format -%} + {{ date | date(format=language_format, locale=date_locale) }} +{%- elif config.extra.short_date_format and short -%} + {{ date | date(format=config.extra.short_date_format, locale=date_locale) }} +{%- elif config.extra.long_date_format and not short -%} + {{ date | date(format=config.extra.long_date_format, locale=date_locale) }} +{%- elif not config.extra.short_date_format and date_locale == "en_GB" -%} + {%- set day = date | date(format='%-d') | int -%} + + {%- if day in [11, 12, 13] -%} + {%- set suffix = "th" -%} + {%- else -%} + {%- set last_digit = day % 10 -%} + {%- if last_digit == 1 -%} + {%- set suffix = "st" -%} + {%- elif last_digit == 2 -%} + {%- set suffix = "nd" -%} + {%- elif last_digit == 3 -%} + {%- set suffix = "rd" -%} + {%- else -%} + {%- set suffix = "th" -%} + {%- endif -%} + {%- endif -%} + + {#- Return the date. -#} + {{ date | date(format="%-d") }}{{ suffix }} + {%- if short == true -%} + {{ date | date(format=" %b %Y") }} + {%- else -%} + {{ date | date(format=" %B %Y") }} + {%- endif -%} +{%- else -%} + {%- if short -%} + {{ date | date(format="%-d %b %Y", locale=date_locale) }} + {%- else -%} + {{ date | date(format="%d %b %Y", locale=date_locale) }} + {%- endif -%} +{%- endif -%} + +{%- endmacro -%} diff --git a/templates/macros/list_posts.html b/templates/macros/list_posts.html new file mode 100644 index 0000000..2076194 --- /dev/null +++ b/templates/macros/list_posts.html @@ -0,0 +1,163 @@ +{# `metadata` can be "dates", "indexes" or both (e.g. "dates indexes" or "indexes dates"). #} +{# If both, the order doesn't matter and indexes will always be displayed before dates. #} +{# It would also work with arrays (e.g. ["dates"] or ["indexes"] or even ["indexes","dates"]). #} +{# Nevertheless, arrays cannot be used as a default value for a macro parameter in Tera (see https://github.com/Keats/tera/issues/710). #} +{# `paginator` is only used to compute indexes metadata and can be let empty otherwise. #} +{% macro list_posts(posts, all_posts="", max=999999, metadata="dates", language_strings="", section_path="", paginator="", pinned_first=false, current_page=1) %} + +{%- set separator = config.extra.separator | default(value="•") -%} + +{# Separate pinned and regular posts from all_posts if available, otherwise from posts #} +{% if pinned_first %} + {% set source_posts = all_posts | default(value=posts) %} + {% set pinned_posts = [] %} + {% set regular_posts = [] %} + {% for post in source_posts %} + {% if post.extra.pinned %} + {% set_global pinned_posts = pinned_posts | concat(with=post) %} + {% else %} + {% set_global regular_posts = regular_posts | concat(with=post) %} + {% endif %} + {% endfor %} + + {# On page 1 or when no pagination, show pinned then regular #} + {% if current_page == 1 %} + {% if paginator %} + {# With pagination: pinned + current page's posts #} + {% set display_posts = pinned_posts | concat(with=posts) %} + {% else %} + {# Without pagination: pinned + regular (no duplicates) #} + {% set display_posts = pinned_posts | concat(with=regular_posts) %} + {% endif %} + {% else %} + {% set display_posts = posts %} + {% endif %} +{% else %} + {% set display_posts = posts %} +{% endif %} + +
+ {# Display posts #} + {% for post in display_posts %} + {% if loop.index <= max %} + {% if loop.index == max or loop.last %} + {% set bottom_divider = false %} + {% else %} + {% set bottom_divider = true %} + {% endif %} + +
+
    + {%- if "indexes" in metadata -%} + {%- set post_index = loop.index -%} + {%- set number_of_posts = posts | length -%} + {# in case we have a pager, the index has been computed for the current page. #} + {%- if paginator -%} + {%- set number_of_posts = paginator.total_pages -%} + {%- set number_of_other_pages = paginator.current_index - 1 -%} + {%- set posts_per_page = paginator.paginate_by -%} + {%- set posts_in_other_pages = number_of_other_pages * posts_per_page -%} + {%- set post_index = posts_in_other_pages + post_index -%} + {%- endif -%} + {%- if macros_settings::evaluate_setting_priority(setting="post_listing_index_reversed", page=section, default_global_value=false) == "true" -%} + {# index starts at 1 instead of 0 #} + {%- set post_index = number_of_posts + 1 - post_index -%} + {%- endif -%} +
  • {{ post_index }}
  • + {%- endif -%} + + {%- if "dates" in metadata -%} + {%- set allowed_post_listing_dates = ["date", "updated", "both"] -%} + {#- Calling the hierarchy macro here causes an error due to the "get parents" part of the macro. -#} + {#- This seems cleaner. -#} + {%- set post_listing_date = section.extra.post_listing_date | default(value=config.extra.post_listing_date) | default(value="date") -%} + {%- if post_listing_date not in allowed_post_listing_dates -%} + {{ throw(message="ERROR: Invalid value for config.extra.post_listing_date. Allowed values are 'date', 'updated', or 'both'.") }} + {%- endif -%} + + {%- set show_date = post.date and post_listing_date == "date" or post.date and post_listing_date == "both" or post.date and post_listing_date == "updated" and not post.updated -%} + {%- set show_updated = post.updated and post_listing_date == "updated" or post.updated and post_listing_date == "both" -%} + + {%- if show_date or show_updated -%} + {%- if show_date -%} +
  • {{- macros_format_date::format_date(date=post.date, short=false, language_strings=language_strings) -}}
  • + {%- endif -%} + {%- if show_date and show_updated -%} +
  • {{- separator -}}
  • + {%- endif -%} + {%- if show_updated -%} + {%- set last_updated_str = macros_translate::translate(key="last_updated_on", default="Updated on $DATE", language_strings=language_strings) -%} + {%- set formatted_date = macros_format_date::format_date(date=post.updated, short=true, language_strings=language_strings) -%} + {%- set updated_str = last_updated_str | replace(from="$DATE", to=formatted_date) -%} +
  • {{ updated_str }}
  • + {%- endif -%} + {%- endif -%} + {%- endif -%} + + {% if post.extra.local_image or post.extra.remote_image %} +
  • + + {% if post.extra.local_image %} + {% set meta = get_image_metadata(path=post.extra.local_image, allow_missing=true) %} + {{ post.extra.local_image }} + {% elif post.extra.remote_image %} + {{ post.extra.remote_image }} + {% endif %} + +
  • + {% endif %} + + {% if post.draft %} +
  • {{ macros_translate::translate(key="draft", default="DRAFT", language_strings=language_strings) }}
  • + {% endif %} +
+
+ +
+
+ {% if pinned_first and post.extra.pinned %} +
+ + {{ macros_translate::translate(key="pinned", default="Pinned", language_strings=language_strings) }} +
+ {% endif %} + +

+ {{ post.title }} +

+ + {% if post.taxonomies.tags %} +
+ {% for tag in post.taxonomies.tags %} + {{ tag }} + {% endfor %} +
+ {% endif %} + +
+ {% if post.description %} +

{{ post.description | markdown(inline=true) | safe }}

+ {% elif post.summary %} +

{{ post.summary | markdown(inline=true) | trim_end_matches(pat=".") | safe }}…

+ {% endif %} +
+ {{ macros_translate::translate(key="read_more", default="Read more", language_strings=language_strings) }}  +
+
+ {% endif %} + {% if not loop.last %} + {% if loop.index == max %} + + {% endif %} + {% endif %} + {% endfor %} +
+{% endmacro %} diff --git a/templates/macros/page_header.html b/templates/macros/page_header.html new file mode 100644 index 0000000..daa8d02 --- /dev/null +++ b/templates/macros/page_header.html @@ -0,0 +1,18 @@ +{% macro page_header(title, show_feed_icon=false) %} + +{% set rel_attributes = macros_rel_attributes::rel_attributes() | trim %} + + +{%- set blank_target = macros_target_attribute::target_attribute(new_tab=config.markdown.external_links_target_blank) -%} + +

+ {{ title -}} + {% if show_feed_icon %} + {%- set feed_url = feed_utils::get_feed_url() -%} + + {% endif %} +

+ +{% endmacro page_header %} diff --git a/templates/macros/rel_attributes.html b/templates/macros/rel_attributes.html new file mode 100644 index 0000000..71672c7 --- /dev/null +++ b/templates/macros/rel_attributes.html @@ -0,0 +1,19 @@ +{% macro rel_attributes() %} + +{%- set rel_attributes = [] -%} +{%- if config.markdown.external_links_target_blank -%} + {%- set rel_attributes = rel_attributes | concat(with="noopener") -%} +{%- endif -%} +{# https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel#nofollow #} +{# This is ignored, as it doesn't make sense to set `nofollow` on projects or social links. #} +{# {%- if config.markdown.external_links_no_follow -%} + {%- set rel_attributes = rel_attributes | concat(with="nofollow") -%} +{%- endif -%} #} +{%- if config.markdown.external_links_no_referrer -%} + {%- set rel_attributes = rel_attributes | concat(with="noreferrer") -%} +{%- endif -%} + +{# Return the array of rel attributes joined by a space #} +{{- rel_attributes | join(sep=" ") -}} + +{% endmacro rel_attributes %} diff --git a/templates/macros/series_page.html b/templates/macros/series_page.html new file mode 100644 index 0000000..d5704a1 --- /dev/null +++ b/templates/macros/series_page.html @@ -0,0 +1,162 @@ +{# +Those macros deal with introduction and navigation for series pages. +Using macros have been prefered over partial inclusion or inline code to make sure series_ordered_pages is forced to be used. +A section's pages natural order is invalid in case of reversed pagination which would lead to invalid series' pages order. +To prevent this, pages are ordered correctly in a separate variable which must be used instead of the series section pages. +#} + +{# +Computes the introduction of a series's page. + +Parameters: + - `page`: The page object being part of the series. + - `series_section`: The series' section the page belongs to. + - `series_ordered_pages`: The series' pages properly ordered (see at the top of this file for an explanation). + - `language_strings`: A dictionary containing the translation strings. +#} +{% macro process_series_template(template_type, page, series_section, series_ordered_pages, language_strings) %} + {%- if "series" in series_section.extra and series_section.extra.series -%} + {# Prepare variables for substitution #} + {%- set series_title = series_section.title -%} + {%- set series_permalink = series_section.permalink -%} + {%- set series_html_link = '' ~ series_section.title ~ '' -%} + {# Build series pages list #} + {%- set series_pages_list = [] -%} + {%- for series_page in series_ordered_pages -%} + {%- if series_page.relative_path == page.relative_path -%} + {%- set series_pages_list_item = '
  • ' ~ series_page.title ~ '
  • ' -%} + {%- else -%} + {%- set series_pages_list_item = '
  • ' ~ series_page.title ~ '
  • ' -%} + {%- endif -%} + {%- set_global series_pages_list = series_pages_list | concat(with=series_pages_list_item) -%} + {%- endfor -%} + {%- set series_pages_list = series_pages_list | join(sep="") -%} + {%- if macros_settings::evaluate_setting_priority(setting="post_listing_index_reversed", page=series_section, default_global_value=false) == "true" -%} + {%- set series_pages_ordered_list = '
      ' ~ series_pages_list ~ '
    ' -%} + {%- else -%} + {%- set series_pages_ordered_list = '
      ' ~ series_pages_list ~ '
    ' -%} + {%- endif -%} + {%- set series_pages_unordered_list = '' -%} + + {# Get page position and navigation info #} + {%- set series_pages_number = 0 -%} + {%- set series_page_index = 0 -%} + {%- set first_page = series_ordered_pages | first -%} + {%- set is_found = false -%} + + {%- for series_page in series_ordered_pages -%} + {%- set_global series_pages_number = series_pages_number + 1 -%} + {%- if series_page.relative_path == page.relative_path -%} + {%- set_global series_page_index = series_pages_number -%} + {%- set_global is_found = true -%} + {%- else -%} + {%- if not is_found -%} + {%- set_global prev_page = series_page -%} + {%- elif not next_page is defined -%} + {%- set_global next_page = series_page -%} + {%- endif -%} + {%- endif -%} + {%- endfor -%} + + {# Determine template to use based on available navigation #} + {%- set position = "middle" -%} + {%- if prev_page is defined and not next_page is defined -%} + {%- set_global position = "prev_only" -%} + {%- elif next_page is defined and not prev_page is defined -%} + {%- set_global position = "next_only" -%} + {%- endif -%} + + {# Get template from config #} + {%- set templates_key = "series_" ~ template_type ~ "_templates" -%} + {%- set template = "" -%} + {%- if series_section.extra[templates_key] is defined -%} + {%- if series_section.extra[templates_key][position] is defined -%} + {%- set_global template = series_section.extra[templates_key][position] -%} + {%- elif series_section.extra[templates_key].default is defined -%} + {%- set_global template = series_section.extra[templates_key].default -%} + {%- endif -%} + {%- endif -%} + + {# Prepare navigation variables #} + {%- if prev_page is defined -%} + {%- set prev_title = prev_page.title -%} + {%- set prev_permalink = prev_page.permalink -%} + {%- set prev_html_link = '' ~ prev_page.title ~ '' -%} + {%- set prev_description = prev_page.description | default(value="") -%} + {%- endif -%} + {%- if next_page is defined -%} + {%- set next_title = next_page.title -%} + {%- set next_permalink = next_page.permalink -%} + {%- set next_html_link = '' ~ next_page.title ~ '' -%} + {%- set next_description = next_page.description | default(value="") -%} + {%- endif -%} + + {# Replace standard variables #} + {%- set template = template + | replace(from="$SERIES_TITLE", to=series_title) + | replace(from="$SERIES_PERMALINK", to=series_permalink) + | replace(from="$SERIES_HTML_LINK", to=series_html_link) + | replace(from="$FIRST_TITLE", to=first_page.title) + | replace(from="$FIRST_HTML_LINK", to='' ~ first_page.title ~ '') + | replace(from="$SERIES_PAGES_NUMBER", to=series_pages_number | as_str) + | replace(from="$SERIES_PAGE_INDEX", to=series_page_index | as_str) + | replace(from="$SERIES_PAGES_OLIST", to=series_pages_ordered_list) + | replace(from="$SERIES_PAGES_ULIST", to=series_pages_unordered_list) + -%} + + {# Replace navigation variables if they exist #} + {%- if prev_page is defined -%} + {%- set template = template + | replace(from="$PREV_TITLE", to=prev_title) + | replace(from="$PREV_PERMALINK", to=prev_permalink) + | replace(from="$PREV_HTML_LINK", to=prev_html_link) + | replace(from="$PREV_DESCRIPTION", to=prev_description) + -%} + {%- endif -%} + + {%- if next_page is defined -%} + {%- set template = template + | replace(from="$NEXT_TITLE", to=next_title) + | replace(from="$NEXT_PERMALINK", to=next_permalink) + | replace(from="$NEXT_HTML_LINK", to=next_html_link) + | replace(from="$NEXT_DESCRIPTION", to=next_description) + -%} + {%- endif -%} + + {# Custom placeholders #} + {%- if series_section.extra.series_template_placeholders is defined -%} + {%- set missing_vars = [] -%} + {%- for placeholder in series_section.extra.series_template_placeholders -%} + {%- if placeholder in template -%} + {%- set var_name = placeholder | replace(from="$", to="") | lower -%} + {%- if page.extra.series_template_variables is defined and page.extra.series_template_variables[var_name] is defined -%} + {%- set_global template = template | replace(from=placeholder, to=page.extra.series_template_variables[var_name]) -%} + {%- else -%} + {%- set_global missing_vars = missing_vars | concat(with=var_name) -%} + {%- endif -%} + {%- endif -%} + {%- endfor -%} + {%- if missing_vars | length > 0 -%} + {%- set missing_vars_str = missing_vars | join(sep=", ") -%} + {{ throw(message="ERROR: The following variables are included in this page's series templates (`series_template_placeholders`) but have not been set in the `series_template_variables` of this page: " ~ missing_vars_str) }} + {%- endif -%} + {%- endif -%} + + {# Output the processed template if not empty #} + {%- if template | length > 0 -%} +
    + {{ template | markdown | safe }} +
    + {%- endif -%} + {%- endif -%} +{% endmacro %} + +{# Macro for series introduction #} +{% macro get_introduction(page, series_section, series_ordered_pages, language_strings) %} + {{ macros_series_page::process_series_template(template_type="intro", page=page, series_section=series_section, series_ordered_pages=series_ordered_pages, language_strings=language_strings) }} +{% endmacro %} + +{# Macro for series outro #} +{% macro get_outro(page, series_section, series_ordered_pages, language_strings) %} + {{ macros_series_page::process_series_template(template_type="outro", page=page, series_section=series_section, series_ordered_pages=series_ordered_pages, language_strings=language_strings) }} +{% endmacro %} diff --git a/templates/macros/settings.html b/templates/macros/settings.html new file mode 100644 index 0000000..d237d7a --- /dev/null +++ b/templates/macros/settings.html @@ -0,0 +1,68 @@ +{# +Evaluates the priority of a particular setting across different scopes. + +The priority is as follows: page > section > config. + +Parameters: + - setting: The name of the setting to evaluate. + - page: The page object containing settings. + - default_global_value: The setting's default value. +#} + +{% macro evaluate_setting_priority(setting, page, section="", default_global_value="") %} + +{%- if section -%} + {%- set current_section = section -%} +{%- elif page -%} + {%- set current_section = "" -%} + {#- Retrieve last ancestor to determine current section, if applicable -#} + {%- if page.ancestors | length > 0 -%} + {%- set last_ancestor = page.ancestors | slice(start=-1) -%} + {%- set_global current_section = get_section(path=last_ancestor.0, metadata_only=true) -%} + {%- else -%} + {#- We're likely in a nested page. Try to find the parent page or nearest section. -#} + {%- set components = page.components -%} + {%- for i in range(start=1, end=components | length) -%} + {%- if lang == config.default_language -%} + {%- set potential_path = components | slice(end=components | length - i) | join(sep="/") -%} + {%- set potential_page = potential_path ~ "/index.md" -%} + {%- set potential_section = potential_path ~ "/_index.md" -%} + {%- else -%} + {%- set potential_path = components | slice(start=1, end=components | length - i) | join(sep="/") -%} + {%- set potential_page = potential_path ~ "/index." ~ lang ~ ".md" -%} + {%- set potential_section = potential_path ~ "/_index." ~ lang ~ ".md" -%} + {%- endif -%} + {#- Check for parent page first. -#} + {%- set page_data = load_data(path=potential_page, required=false) -%} + {%- if page_data -%} + {%- set_global current_section = get_page(path=potential_page) -%} + {%- break -%} + {%- endif -%} + {#- No parent page, check for section. -#} + {%- set section_data = load_data(path=potential_section, required=false) -%} + {%- if section_data -%} + {%- set_global current_section = get_section(path=potential_section, metadata_only=true) -%} + {%- break -%} + {%- endif -%} + {%- endfor -%} + {%- endif -%} +{%- endif -%} + +{%- set priority_order = [ + page.extra[setting] | default(value=""), + current_section.extra[setting] | default(value=""), + config.extra[setting] | default(value="") +] -%} + +{%- set output = default_global_value -%} + +{%- for value in priority_order -%} + {%- if value != "" -%} + {%- set_global output = value -%} + {%- break -%} + {%- endif -%} +{%- endfor -%} + +{{- output -}} + +{% endmacro %} diff --git a/templates/macros/table_of_contents.html b/templates/macros/table_of_contents.html new file mode 100644 index 0000000..18a3ab6 --- /dev/null +++ b/templates/macros/table_of_contents.html @@ -0,0 +1,54 @@ +{% macro toc(page, header, language_strings="") %} + +{%- set toc_levels = page.extra.toc_levels | default(value=3) -%} + +{% if page.extra.toc_ignore_pattern %} + {%- set toc_ignore_pattern = page.extra.toc_ignore_pattern -%} +{% endif %} + +
    + {% if header %} +

    {{ macros_translate::translate(key="table_of_contents", default="Table of Contents", language_strings=language_strings) }}

    + {% endif %} + +
      + {% for h1 in page.toc %} + {# Only render headers if there's no ignore pattern, or if the header text doesn't match the pattern. #} + {% if not toc_ignore_pattern or not (h1.title is matching(toc_ignore_pattern)) %} +
    • {{ h1.title }} + {% if h1.children and toc_levels > 1 %} +
        + {% for h2 in h1.children %} + {% if not toc_ignore_pattern or not (h2.title is matching(toc_ignore_pattern)) %} +
      • {{ h2.title }} + {% if h2.children and toc_levels > 2 %} +
          + {% for h3 in h2.children %} + {% if not toc_ignore_pattern or not (h3.title is matching(toc_ignore_pattern)) %} +
        • {{ h3.title }} + {% if h3.children and toc_levels > 3 %} +
            + {% for h4 in h3.children %} + {% if not toc_ignore_pattern or not (h4.title is matching(toc_ignore_pattern)) %} +
          • {{ h4.title }}
          • + {% endif %} + {% endfor %} +
          + {% endif %} +
        • + {% endif %} + {% endfor %} +
        + {% endif %} +
      • + {% endif %} + {% endfor %} +
      + {% endif %} +
    • + {% endif %} + {% endfor %} +
    +
    + +{% endmacro toc %} diff --git a/templates/macros/target_attribute.html b/templates/macros/target_attribute.html new file mode 100644 index 0000000..2da5b9d --- /dev/null +++ b/templates/macros/target_attribute.html @@ -0,0 +1,11 @@ +{% macro target_attribute(new_tab) %} + +{%- set blank_target = "" -%} + +{%- if new_tab -%} + {%- set blank_target = "target=_blank" -%} +{%- endif -%} + +{{ blank_target }} + +{% endmacro target_attribute %} diff --git a/templates/macros/translate.html b/templates/macros/translate.html new file mode 100644 index 0000000..1b138dd --- /dev/null +++ b/templates/macros/translate.html @@ -0,0 +1,72 @@ +{#- Dynamically selects the appropriate translation key based on the provided `number` and `lang` context. +If a `number` is provided, the macro will attempt to pluralize the translation key based on the language's rules. + +Parameters: +- `key`: The base key for the translation string, matching the i18n files. Example: `results` to get `zero_results`, `one_results`, `many_results`, etc. +- `number`: Optional. The numerical value associated with the key. +- `language_strings`: A dictionary containing the translation strings. +- `default`: A default string to use if no translation is found for the key. +- `replace`: Optional. If `true`, the macro will replace the `$NUMBER` placeholder in the translation string with the provided `number`. + +The macro supports special pluralization rules for: +- Arabic (`ar`): Has unique forms for zero, one, two, few, and many. +- Slavic languages: Pluralization depends on the last digit of the number, with exceptions for numbers ending in 11-14. + +NOTE: If the logic for pluralization is modified, it needs to be replicated on the JavaScript search. +Files: static/js/searchElasticlunr.js and its minified version at static/js/searchElasticlunr.min.js +Function name: getPluralizationKey -#} +{% macro translate(key, number=-1, language_strings="", default="", replace=true) %} + {%- set slavic_plural_languages = ["uk", "be", "bs", "hr", "ru", "sr"] -%} + + {%- set key_prefix = "" -%} + {#- `zero_` and `one_` are common cases. We handle "many" (plural) later, after language-specific pluralization -#} + {%- if number == 0 -%} + {%- set key_prefix = "zero_" -%} + {%- elif number == 1 -%} + {%- set key_prefix = "one_" -%} + {%- endif -%} + + {#- Pluralization -#} + {%- if number != -1 and key_prefix == "" -%} + {#- Arabic -#} + {%- if lang == "ar" -%} + {%- set modulo = number % 100 -%} + {%- if number == 2 -%} + {%- set key_prefix = "two_" -%} + {%- elif modulo >= 3 and modulo <= 10 -%} + {%- set key_prefix = "few_" -%} + {%- else -%} + {%- set key_prefix = "many_" -%} + {%- endif -%} + {#- Slavic languages like Russian or Ukrainian -#} + {%- elif lang in slavic_plural_languages -%} + {%- set modulo10 = number % 10 -%} + {%- set modulo100 = number % 100 -%} + {%- if modulo10 == 1 and modulo100 != 11 -%} + {%- set key_prefix = "one_" -%} + {%- elif modulo10 >= 2 and modulo10 <= 4 -%} + {%- if modulo100 >= 12 and modulo100 <= 14 -%} + {%- set key_prefix = "many_" -%} + {%- else -%} + {%- set key_prefix = "few_" -%} + {%- endif -%} + {%- else -%} + {%- set key_prefix = "many_" -%} + {%- endif -%} + {%- else -%} + {#- Default pluralization -#} + {#- Zero and one are already handled -#} + {%- set key_prefix = "many_" -%} + {%- endif -%} + {%- endif -%} + + {#- Translated string -#} + {%- set final_key = key_prefix ~ key -%} + {%- set translated_text = language_strings[final_key] | default(value=default) | safe -%} + + {#- Replace $NUMBER with the number -#} + {%- if replace -%} + {%- set translated_text = translated_text | replace(from="$NUMBER", to=number | as_str) -%} + {%- endif -%} + {{- translated_text -}} +{% endmacro %} diff --git a/templates/page.html b/templates/page.html new file mode 100644 index 0000000..0dff1a7 --- /dev/null +++ b/templates/page.html @@ -0,0 +1,368 @@ +{% extends "base.html" %} + +{% block main_content %} +{%- set separator = config.extra.separator | default(value="•") -%} + +{%- set rel_attributes = macros_rel_attributes::rel_attributes() | trim -%} + +{%- set blank_target = macros_target_attribute::target_attribute(new_tab=config.markdown.external_links_target_blank) -%} + +{# Debugging #} +{#
    +    Page path: {{ page.path }}
    +    Page components: {{ page.components | join(sep=", ") }}
    +    Page ancestors: {{ page.ancestors | join(sep=", ") }}
    +    Current language: {{ lang }}
    +    Default language: {{ config.default_language }}
    +    Current section: {% if current_section %}{{ current_section.path }}{% else %}None{% endif %}
    +    Page extra: {{ page.extra | json_encode() }}
    +    {% if section -%}
    +        {%- set current_section = section -%}
    +    {%- elif page -%}
    +        {%- set current_section = "" -%}
    +        {%- if page.ancestors | length > 0 -%}
    +            {%- set last_ancestor = page.ancestors | slice(start=-1) -%}
    +            {%- set_global current_section = get_section(path=last_ancestor.0, metadata_only=true) -%}
    +        {%- else -%}
    +            {%- set components = page.components -%}
    +            {%- for i in range(start=1, end=components | length) -%}
    +                {%- if lang == config.default_language -%}
    +                    {%- set potential_path = components | slice(end=components | length - i) | join(sep="/") -%}
    +                    {%- set potential_page = potential_path ~ "/index.md" -%}
    +                    {%- set potential_section = potential_path ~ "/_index.md" -%}
    +                {%- else -%}
    +                    {%- set potential_path = components | slice(start=1, end=components | length - i) | join(sep="/") -%}
    +                    {%- set potential_page = potential_path ~ "/index." ~ lang ~ ".md" -%}
    +                    {%- set potential_section = potential_path ~ "/_index." ~ lang ~ ".md" -%}
    +                {%- endif -%}
    +                Checking parent page: {{ potential_page }}
    +                {%- set page_data = load_data(path=potential_page, required=false) -%}
    +                {%- if page_data -%}
    +                    {%- set_global current_section = get_page(path=potential_page) %}
    +    Parent page found: {{ current_section.path }}
    +                    {%- break -%}
    +                {%- endif -%}
    +                Checking section: {{ potential_section }}
    +                {%- set section_data = load_data(path=potential_section, required=false) -%}
    +                {%- if section_data -%}
    +                    {%- set_global current_section = get_section(path=potential_section, metadata_only=true) -%}
    +                    Section found: {{ current_section.path }}
    +                    {%- break -%}
    +                {%- endif -%}
    +            {%- endfor -%}
    +        {%- endif -%}
    +    {%- endif %}
    +Found nearest parent/section: {% if current_section %}{{ current_section.path }}{% else %}None{% endif %}
    +Current section extra: {% if current_section %}{{ current_section.extra | json_encode() }}{% else %}None{% endif %}
    +
    + + {% set settings_to_test = [ + "iine", + "iine_icon", + "enable_cards_tag_filtering", + "footnote_backlinks", + "add_src_to_code_block", + "force_codeblock_ltr", + "copy_button", + "katex", + "quick_navigation_buttons", + "show_reading_time", + "show_date", + "show_author", + "show_remote_changes", + "toc", + "show_previous_next_article_links", + "invert_previous_next_article_links", + "previous_next_article_links_full_width", + "enable_csp", + ] %} + + + + + + + + + + + + + {% for setting in settings_to_test %} + + + + + + + + {% endfor %} + +
    settingpagesectionconfigmacro output
    {{ setting }}{{ page.extra[setting] | default(value="⬛") }}{{ current_section.extra[setting] | default(value="⬛") }}{{ config.extra[setting] | default(value="⬛") }}{{ macros_settings::evaluate_setting_priority(setting=setting, page=page) }}
    + #} + +{# {{ __tera_context }} #} +{# End debugging #} + +
    +
    +

    + {{ page.title | markdown(inline=true) | safe }} +

    + + +
      + {#- Draft indicator -#} + {% if page.draft %} +
    • {{ macros_translate::translate(key="draft", default="DRAFT", language_strings=language_strings) }}
    • + {% endif %} + + {#- Author(s) -#} + {%- if page.authors or config.author and macros_settings::evaluate_setting_priority(setting="show_author", page=page, default_global_value=false) == "true" -%} + {%- if page.authors -%} + {%- set author_list = page.authors -%} + {%- else -%} + {%- set author_list = [config.author] -%} + {%- endif -%} + + {%- if author_list | length == 1 -%} + {%- set author_string = '' ~ author_list.0 ~ '' -%} + {%- else -%} + {%- set last_author = author_list | last -%} + {%- set other_authors = author_list | slice(end=-1) -%} + {%- set author_separator = macros_translate::translate(key="author_separator", default=", ", language_strings=language_strings) -%} + {%- set author_separator = '' ~ author_separator ~ '' -%} + {%- set conjunction = macros_translate::translate(key="author_conjunction", default=" and ", language_strings=language_strings) -%} + {%- set conjunction = '' ~ conjunction ~ '' -%} + {%- set author_string = other_authors | join(sep=author_separator) -%} + {%- set author_string = author_string ~ conjunction ~ last_author -%} + {%- set author_string = '' ~ author_string ~ '' -%} + {%- endif -%} + + {%- set by_author = macros_translate::translate(key="by_author", default="By $AUTHOR", language_strings=language_strings) -%} +
    • {{ by_author | replace(from="$AUTHOR", to=author_string) | safe }}
    • + {%- set previous_visible = true -%} + {%- endif -%} + + {%- if config.extra.hcard and config.extra.hcard.enable and ( not author_list or author_list is containing(config.author)) -%} + {% include "partials/hcard_small.html" %} + {%- endif -%} + + {%- set separator_with_class = ""-%} + + {#- Date -#} + {%- if page.date and macros_settings::evaluate_setting_priority(setting="show_date", page=page, default_global_value=true) == "true" -%} +
    • + {#- Variable to keep track of whether we've shown a section, to avoid separators as the first element -#} + {%- set previous_visible = true -%} + {%- endif -%} + + {#- Reading time -#} + {%- if macros_settings::evaluate_setting_priority(setting="show_reading_time", page=page, default_global_value=true) == "true" -%} +
    • {%- if previous_visible -%}{{ separator_with_class | safe }}{%- endif -%}{{ macros_translate::translate(key="min_read", number=page.reading_time, default="$NUMBER min read", language_strings=language_strings) }}
    • + {%- set previous_visible = true -%} + {%- endif -%} + + {#- Tags -#} + {%- if page.taxonomies and page.taxonomies.tags -%} +
    • {%- if previous_visible -%}{{ separator_with_class | safe }}{%- endif -%}{{- macros_translate::translate(key="tags", default="tags", language_strings=language_strings) | capitalize -}}: 
    • + {%- for tag in page.taxonomies.tags -%} +
    • {{ tag }} + {%- if not loop.last -%} + ,  + {%- endif -%} +
    • + {%- endfor -%} + {%- set previous_visible = true -%} + {%- endif -%} + + {#- Last updated on -#} + {% if page.updated %} + {%- set last_updated_str = macros_translate::translate(key="last_updated_on", default="Updated on $DATE", language_strings=language_strings) -%} + {%- set formatted_date = macros_format_date::format_date(date=page.updated, short=true, language_strings=language_strings) -%} + {%- set updated_str = last_updated_str | replace(from="$DATE", to=formatted_date) -%} + {%- set previous_visible = true -%} +
    + + {#- A page is part of a series if one of the sections above (whether it is transparent or not) has the `extra.series` parameter set to true. -#} + {#- As a series might be a transparent section in order to mix up its articles with those of the section just above or the root, -#} + {#- there is no other way but to compute the potential path of each ancestor section related to the page and look for the first one being a series. -#} + {#- Using the `ancestors` field of a section is not possible because transparent sections are not present in this field. -#} + {%- set series_path_components = [] -%} + {%- set section_paths = [] -%} + {%- for path in page.relative_path | split(pat="/") | slice(end=-1) -%} + {%- set_global series_path_components = series_path_components | concat(with=path) -%} + {%- set section_path = series_path_components | concat(with="_index.md") | join(sep="/") -%} + {%- set_global section_paths = section_paths | concat(with=section_path) -%} + {%- endfor -%} + {#- The series the page is part of is the closest section flagged as a series, if any -#} + {%- for section_path in section_paths | reverse -%} + {%- set section_file_exists = load_data(path=section_path, required=false) -%} + {%- if section_file_exists -%} + {%- set loaded_section = get_section(path=section_path,lang=lang) -%} + {%- if "series" in loaded_section.extra and loaded_section.extra.series -%} + {%- set_global series_section = loaded_section -%} + {%- set_global series_ordered_pages = loaded_section.pages -%} + {%- if loaded_section.paginated | default(value=0) > 0 and loaded_section.paginate_reversed -%} + {%- set_global series_ordered_pages = loaded_section.pages | reverse -%} + {%- endif -%} + {%- break -%} + {%- endif -%} + {%- endif -%} + {%- endfor -%} + + {% if page.extra.tldr %} +
    +
    +
    + + TL;DR + +

    {{ page.extra.tldr | markdown | safe }}

    +
    +
    + {% endif %} + + {#- Optional table of contents below the header -#} + {% if page.toc and macros_settings::evaluate_setting_priority(setting="toc", page=page, default_global_value=false) == "true" %} + {{ macros_toc::toc(page=page, header=true, language_strings=language_strings) }} + {% endif %} + + {#- Optional Summary paragraph for readers -#} + {% if page.description %} + + {%- endif -%} + + +
    + {#- Replace series_intro placeholder -#} + {%- set content_with_intro = page.content -%} + {%- if "" in page.content -%} + {%- set series_intro_html = macros_series_page::get_introduction(page=page, series_section=series_section, series_ordered_pages=series_ordered_pages, language_strings=language_strings) -%} + {%- set content_with_intro = content_with_intro | replace(from="", to=series_intro_html) -%} + {%- elif series_section -%} + {%- set series_intro_html = macros_series_page::get_introduction(page=page, series_section=series_section, series_ordered_pages=series_ordered_pages, language_strings=language_strings) -%} + {%- set content_with_intro = series_intro_html ~ content_with_intro -%} + {%- endif -%} + + {#- Handle series_outro placeholder -#} + {%- set processed_content = content_with_intro -%} + {%- if "" in content_with_intro -%} + {%- set series_outro_html = macros_series_page::get_outro(page=page, series_section=series_section, series_ordered_pages=series_ordered_pages, language_strings=language_strings) -%} + {%- set processed_content = processed_content | replace(from="", to=series_outro_html) -%} + {%- elif series_section -%} + {%- set series_outro_html = macros_series_page::get_outro(page=page, series_section=series_section, series_ordered_pages=series_ordered_pages, language_strings=language_strings) -%} + {#- We want the outro at the end of the article, but before footnote definitions -#} + {%- set footnotes_marker = '
      ' -%} + {%- if footnotes_marker in content_with_intro -%} + {%- set content_sections = processed_content | split(pat=footnotes_marker) -%} + {%- set main_content = content_sections | first -%} + {%- set footnotes_content = content_sections | slice(start=1) | join(sep=footnotes_marker) -%} + {%- set processed_content = main_content ~ series_outro_html ~ footnotes_marker ~ footnotes_content -%} + {%- else -%} + {%- set processed_content = processed_content ~ series_outro_html -%} + {%- endif -%} + {%- endif -%} + + {#- Replace TOC and render final content -#} + {#- The replace pattern is used to enable arbitrary locations for the Table of Contents -#} + {#- This is Philipp Oppermann's workaround: https://github.com/getzola/zola/issues/584#issuecomment-474329637 -#} + {{ processed_content | replace(from="", to=macros_toc::toc(page=page, header=false, language_strings=language_strings)) | safe }} +
    + + {#- iine button -#} + {%- if macros_settings::evaluate_setting_priority(setting="iine", page=page, default_global_value=false) == "true" -%} + {% include "partials/iine_button.html" %} + {%- endif -%} + + {% if macros_settings::evaluate_setting_priority(setting="show_previous_next_article_links", page=page, default_global_value=true) == "true" %} + {%- if page.lower or page.higher -%} + {% set next_label = macros_translate::translate(key="next", default="Next", language_strings=language_strings) %} + {% set prev_label = macros_translate::translate(key="prev", default="Prev", language_strings=language_strings) %} + {% if macros_settings::evaluate_setting_priority(setting="invert_previous_next_article_links", page=page, default_global_value=true) == "true" %} + {% if page.higher %} + {% set left_link = page.higher.permalink %} + {% set left_label = prev_label %} + {% set left_title = page.higher.title %} + {% endif %} + {% if page.lower %} + {% set right_link = page.lower.permalink %} + {% set right_label = next_label %} + {% set right_title = page.lower.title %} + {% endif %} + {% else %} + {% if page.lower %} + {% set left_link = page.lower.permalink %} + {% set left_label = next_label %} + {% set left_title = page.lower.title %} + {% endif %} + {% if page.higher %} + {% set right_link = page.higher.permalink %} + {% set right_label = prev_label %} + {% set right_title = page.higher.title %} + {% endif %} + {% endif %} + {% if macros_settings::evaluate_setting_priority(setting="previous_next_article_links_full_width", page=page, default_global_value=true) == "true" %} + {%- set full_width_class = "full-width" -%} + {% endif %} + + {%- endif -%} + {%- endif -%} + + {#- Comments -#} + {#- Check if comments are enabled, checking that they are not disabled on the specific page -#} + {% set systems = ["giscus", "utterances", "hyvortalk", "isso"] %} + {% set enabled_systems = 0 %} + {% set comment_system = "" %} + + {% for system in systems %} + {% set global_enabled = config.extra[system].enabled_for_all_posts | default(value=false) %} + {% set page_enabled = page.extra[system] | default(value=global_enabled) %} + {% set is_enabled = global_enabled and page_enabled != false or page_enabled == true %} + + {% if is_enabled %} + {% set_global comment_system = system %} + {% set_global enabled_systems = enabled_systems + 1 %} + {% endif %} + {% endfor %} + {#- Ensure only one comment system is enabled -#} + {% if enabled_systems > 1 %} + {{ throw(message="ERROR: Multiple comment systems have been enabled for the same page. Check your config.toml and individual page settings to ensure only one comment system is activated at a time.") }} + {% endif %} + {% if comment_system %} + {% include "partials/comments.html" %} + {% endif %} + + {#- Webmentions -#} + {%- set global_webmentions_enabled = config.extra.webmentions.enable | default(value=false) -%} + {%- set page_webmentions_enabled = page.extra.webmentions | default(value=global_webmentions_enabled) -%} + {%- set webmentions_enabled = global_webmentions_enabled and page_webmentions_enabled != false or page_webmentions_enabled == true -%} + {%- if webmentions_enabled -%} + {%- include "partials/webmentions.html" -%} + {%- endif -%} + +
    +
    + +{%- include "partials/extra_features.html" -%} + +{% endblock main_content %} diff --git a/templates/partials/analytics.html b/templates/partials/analytics.html new file mode 100644 index 0000000..6a5d30e --- /dev/null +++ b/templates/partials/analytics.html @@ -0,0 +1,38 @@ +{% set analytics_service = config.extra.analytics.service %} +{% set analytics_id = config.extra.analytics.id | default(value="") %} +{% set self_hosted_url = config.extra.analytics.self_hosted_url | default(value="") %} + +{% if analytics_service == "goatcounter" %} + {# Prevent non-demo sites from using the demo analytics account #} + {% if self_hosted_url == "https://tabi-stats.osc.garden" and config.base_url == "https://welpo.github.io/tabi" or self_hosted_url != "https://tabi-stats.osc.garden" %} + + {% endif %} + +{% elif analytics_service == "umami" %} + + + {% elif analytics_service == "plausible" %} + + +{% endif %} diff --git a/templates/partials/cards_pages.html b/templates/partials/cards_pages.html new file mode 100644 index 0000000..89bdabc --- /dev/null +++ b/templates/partials/cards_pages.html @@ -0,0 +1,46 @@ +{%- set rel_attributes = macros_rel_attributes::rel_attributes() | trim -%} +{%- set max_projects = max_projects | default(value=999999) -%} +
    + {%- for page in show_pages %} + {# Used only in main page #} + {% if loop.index > max_projects %} + {% break %} + {% endif %} + {# Determine which URL to use, default is page.permalink #} + {%- set blank_target = macros_target_attribute::target_attribute(new_tab=config.markdown.external_links_target_blank and page.extra.link_to) -%} + + {% set target_url = page.extra.link_to | default(value=page.permalink) %} + + + {% if page.extra.local_image %} + {% set meta = get_image_metadata(path=page.extra.local_image, allow_missing=true) %} + {{ page.extra.local_image }} + {% elif page.extra.remote_image %} + {{ page.extra.remote_image }} + {% else %} +
    + {% endif %} + +
    +

    {{ page.title | markdown(inline=true) | safe }}

    +
    + {% if page.description %} + {{ page.description | markdown(inline=true) | safe }} + {% endif %} +
    +
    +
    + {% endfor -%} +
    diff --git a/templates/partials/comments.html b/templates/partials/comments.html new file mode 100644 index 0000000..1129055 --- /dev/null +++ b/templates/partials/comments.html @@ -0,0 +1,95 @@ +{% set automatic_loading = config.extra[comment_system].automatic_loading %} + +
    + +{% elif comment_system == "utterances" %} + data-repo="{{ config.extra.utterances.repo }}" + {% if config.extra.utterances.issue_term == "slug" %} + data-issue-term="{{ page.slug }}" + {% else %} + data-issue-term="{{ config.extra.utterances.issue_term }}" + {% endif %} + data-label="{{ config.extra.utterances.label }}" + data-light-theme="{{ config.extra.utterances.light_theme }}" + data-dark-theme="{{ config.extra.utterances.dark_theme }}" + data-lazy-loading="{{ config.extra.utterances.lazy_loading }}" + > + +{% elif comment_system == "hyvortalk" %} + data-website-id="{{ config.extra.hyvortalk.website_id }}" + {% if config.extra.hyvortalk.page_id_is_slug %} + data-page-id="{{ page.slug }}" + {% else %} + data-page-id="{{ current_url }}" + {% endif %} + {% if config.extra.hyvortalk.lang %} + data-page-language="{{ config.extra.hyvortalk.lang }}" + {% else %} + data-page-language="{{ lang }}" + {% endif %} + data-page-author="{{ config.extra.hyvortalk.page_author }}" + {% if config.extra.hyvortalk.lazy_loading %} + data-loading="lazy" + {% else %} + data-loading="default" + {% endif %} + > + +{% elif comment_system == "isso" %} + data-endpoint-url="{{ config.extra.isso.endpoint_url }}" + {% if config.extra.isso.page_id_is_slug %} + {%- set default_lang_url = current_path | replace(from='/' ~ lang ~ '/', to = '/') -%} + data-isso-id="{{ default_lang_url }}" + data-title="{{ default_lang_url }}" + {% endif %} + {% if config.extra.isso.lang %} + data-page-language="{{ config.extra.isso.lang }}" + {% else %} + data-page-language="{{ lang }}" + {% endif %} + data-max-comments-top="{{ config.extra.isso.max_comments_top }}" + data-max-comments-nested="{{ config.extra.isso.max_comments_nested }}" + data-avatar="{{ config.extra.isso.avatar }}" + data-voting="{{ config.extra.isso.voting }}" + data-page-author-hashes="{{ config.extra.isso.page_author_hashes }}" + data-lazy-loading="{{ config.extra.isso.lazy_loading }}" + > +{% endif %} + +{% if automatic_loading %} + +{% else %} + + +{% endif %} + + +
    diff --git a/templates/partials/content_security_policy.html b/templates/partials/content_security_policy.html new file mode 100644 index 0000000..e8fa062 --- /dev/null +++ b/templates/partials/content_security_policy.html @@ -0,0 +1,119 @@ + diff --git a/templates/partials/copyright.html b/templates/partials/copyright.html new file mode 100644 index 0000000..b9cfc01 --- /dev/null +++ b/templates/partials/copyright.html @@ -0,0 +1,39 @@ +{%- if config.extra.copyright -%} + {% set copyright = config.extra.copyright %} + {# Try to look for a language-specific copyright notice in the new config setup #} + {%- if config.extra.copyright_translations -%} + {%- if lang in config.extra.copyright_translations -%} + {% set copyright = config.extra.copyright_translations[lang] %} + {%- endif -%} + {%- elif config.extra.translate_copyright -%} + {# Old way to translate the copyright through toml files #} + {{ throw(message="ERROR: The 'translate_copyright' feature has been deprecated. Please set 'copyright_translations' in config.toml. See the documentation: https://welpo.github.io/tabi/blog/mastering-tabi-settings/#copyright") }} + {%- endif -%} + + {# Check for missing variables in the notice #} + {% set copyright_placeholders = ["$AUTHOR", "$TITLE"] %} + {% set missing_vars = [] %} + {% for placeholder in copyright_placeholders %} + {% if placeholder in copyright %} + {# Attempt to retrieve the corresponding variable by trimming the $ sign and converting to lowercase #} + {% set var_name = placeholder | replace(from="$", to="") | lower %} + {% if not config[var_name] %} + {# Append the variable name to the list of missing variables #} + {% set_global missing_vars = missing_vars | concat(with=var_name) %} + {% endif %} + {% endif %} + {% endfor %} + + {% if missing_vars | length > 0 %} + {% set missing_vars_str = missing_vars | join(sep=", ") %} + {{ throw(message="ERROR: The following variables are included in `copyright` but have not been set in the config.toml: " ~ missing_vars_str) }} + {% endif %} + + {# At this point, we know that all variables needed defined, so we can safely override the missing ones #} + {% set author = config.author | default(value="") %} + {% set title = config.title | default(value="") %} + + {# Render the copyright notice, replacing the variables #} + {% set current_year = now() | date(format="%Y") %} +

    {{ copyright | replace(from="$AUTHOR", to=author) | replace(from="$TITLE", to=title) | replace(from="$CURRENT_YEAR", to=current_year) | replace(from="$SEPARATOR", to=separator) | markdown | safe }}

    +{%- endif -%} diff --git a/templates/partials/extra_features.html b/templates/partials/extra_features.html new file mode 100644 index 0000000..50c3337 --- /dev/null +++ b/templates/partials/extra_features.html @@ -0,0 +1,88 @@ +{%- set page_or_section = page | default(value=section) -%} + +{# prepare parameters for evaluate_setting_priority macro #} +{%- set page_s = page | default(value="") -%} +{%- set section_s = section | default(value="") -%} + +{# Quick navigation buttons #} +{% if macros_settings::evaluate_setting_priority(setting="quick_navigation_buttons", page=page_s, section=section_s, default_global_value=false) == "true" %} +
    + {# Button to go show a floating Table of Contents #} + {% if page_or_section.toc %} +
    + + + +
    + {{ macros_toc::toc(page=page_or_section, header=false, language_strings=language_strings) }} +
    +
    + {% endif %} + + {# Button to go to the comment/webmentions section #} + {% if comment_system or config.extra.webmentions.enable %} + {%- if comment_system -%} + {#- Comments are shown above webmentions -#} + {%- set comments_id = "comments" -%} + {%- else -%} + {%- set comments_id = "webmentions" -%} + {%- endif -%} + + + + + {% endif %} + + {# Button to go to the top of the page #} + + + +
    +{% endif %} + +{# Add KaTeX functionality #} +{%- if macros_settings::evaluate_setting_priority(setting="katex", page=page_s, section=section_s, default_global_value=false) == "true" -%} + + +{%- endif -%} + +{# Load mermaid.js #} +{%- if macros_settings::evaluate_setting_priority(setting="mermaid", page=page_s, section=section_s, default_global_value=false) == "true" -%} + {%- if config.extra.serve_local_mermaid | default(value=true) -%} + + {%- else -%} + + {%- endif -%} +{%- endif -%} + +{# Add copy button to code blocks #} +{%- if macros_settings::evaluate_setting_priority(setting="copy_button", page=page_s, section=section_s, default_global_value=true) == "true" -%} + {#- Add hidden HTML elements with the translated strings for the button's interactions -#} + + + +{%- endif -%} + +{# JavaScript to make code block names clickable when they are URLs: https://welpo.github.io/tabi/blog/shortcodes/#show-source-or-path #} +{# Note: "add_src_to_code_block" is deprecated in favor of "code_block_name_links". It will be removed in a future release. #} +{# See https://github.com/welpo/tabi/pull/489 #} +{%- if macros_settings::evaluate_setting_priority(setting="code_block_name_links", page=page_s, section=section_s, default_global_value=false) == "true" + or macros_settings::evaluate_setting_priority(setting="add_src_to_code_block", page=page_s, section=section_s, default_global_value=false) == "true" -%} + +{%- endif -%} + +{# Add backlinks to footnotes #} +{%- if macros_settings::evaluate_setting_priority(setting="footnote_backlinks", page=page_s, section=section_s, default_global_value=false) == "true" -%} + +{%- endif -%} + +{# Add iine.js for the like button #} +{%- if macros_settings::evaluate_setting_priority(setting="iine", page=page_s, section=section_s, default_global_value=false) == "true" -%} + +{%- endif -%} diff --git a/templates/partials/filter_card_tags.html b/templates/partials/filter_card_tags.html new file mode 100644 index 0000000..d40ec2d --- /dev/null +++ b/templates/partials/filter_card_tags.html @@ -0,0 +1,35 @@ +{#- Collect all terms. -#} +{#- We don't use `get_taxonomy` so users aren't forced to use 'tags' -#} +{% set all_terms = [] %} +{% for page in show_pages %} + {% if page.taxonomies %} + {% for tax_name, terms in page.taxonomies %} + {% for term in terms %} + {% set_global all_terms = all_terms | concat(with=term) %} + {% endfor %} + {% endfor %} + {% endif %} +{% endfor %} + +{#- Display unique terms -#} +{% set unique_terms = all_terms | unique | sort %} +{%- if unique_terms | length >= 2 -%} + + {#- Load the script -#} + +{% endif %} diff --git a/templates/partials/footer.html b/templates/partials/footer.html new file mode 100644 index 0000000..db4bd85 --- /dev/null +++ b/templates/partials/footer.html @@ -0,0 +1,127 @@ +{%- set separator = config.extra.separator | default(value="•") -%} + +{%- set rel_attributes = macros_rel_attributes::rel_attributes() | trim -%} + +{%- set blank_target = macros_target_attribute::target_attribute(new_tab=config.markdown.external_links_target_blank) -%} + +{#- Feed icon -#} +{%- set feed_url = feed_utils::get_feed_url() -%} +{%- set should_show_feed = feed_utils::should_show_footer_feed_icon() == "true" -%} + +{%- set should_show_footer_icons = should_show_feed or config.extra.socials or config.extra.email -%} + +
    +
    + + + {# Footer menu #} + + +
    + + {% include "partials/copyright.html" %} + + {# Shows "Powered by Zola & tabi" notice #} + {{ macros_translate::translate(key="powered_by", default="Powered by", language_strings=language_strings) }} + Zola + {{ macros_translate::translate(key="and", default="&", language_strings=language_strings) }} + tabi + + {# Shows link to remote repository #} + {%- if config.extra.remote_repository_url and config.extra.show_remote_source | default(value=true) -%} + {{ separator }} + + {{ macros_translate::translate(key="site_source", default="Site source", language_strings=language_strings) }} + + {%- endif -%} + +
    +
    + + {# Load the decoding script if email is encoded #} + {%- if email_needs_decoding -%} + + {%- endif -%} + + {# Modal structure for search #} + {%- if config.build_search_index -%} + {% include "partials/search_modal.html" %} + {%- endif -%} +
    diff --git a/templates/partials/hcard.html b/templates/partials/hcard.html new file mode 100644 index 0000000..6479da6 --- /dev/null +++ b/templates/partials/hcard.html @@ -0,0 +1,75 @@ +{%- set hcard = config.extra.hcard -%} + +{% set full_name = config.author %} +{% if hcard.full_name %} + {% set full_name = hcard.full_name %} +{% endif %} + +{%- set homepage = config.base_url -%} +{% if hcard.homepage %} + {%- set homepage = hcard.homepage -%} +{% endif %} + +{% if hcard.enable %} + +{% endif %} diff --git a/templates/partials/hcard_small.html b/templates/partials/hcard_small.html new file mode 100644 index 0000000..f30add5 --- /dev/null +++ b/templates/partials/hcard_small.html @@ -0,0 +1,26 @@ +{%- set hcard = config.extra.hcard -%} + +{%- set full_name = config.author -%} +{%- if hcard.full_name -%} + {%- set full_name = hcard.full_name -%} +{%- endif -%} + +{%- set homepage = config.base_url -%} +{%- if hcard.homepage -%} + {%- set homepage = hcard.homepage -%} +{%- endif -%} + +{%- set icon_attr = "" -%} +{%- if hcard.avatar -%} + {%- set icon_attr = "author-icon" -%} +{%- endif -%} + + diff --git a/templates/partials/header.html b/templates/partials/header.html new file mode 100644 index 0000000..ada1f23 --- /dev/null +++ b/templates/partials/header.html @@ -0,0 +1,182 @@ + + + + {%- if macros_settings::evaluate_setting_priority(setting="enable_csp", page=page | default(value=""), section=section | default(value=""), default_global_value="true") == "true" -%} + {%- include "partials/content_security_policy.html" -%} + {%- endif -%} + + + + + {# Site title #} + {%- include "partials/title.html" -%} + + {# Favicon #} + {% if config.extra.favicon %} + + {% endif %} + {% if config.extra.favicon_emoji %} + + {% endif %} + + {# Feeds #} + {% if config.generate_feeds | default(value=config.generate_feed) %} + {% if config.feed_filenames %} + {# Zola 0.19 and newer #} + {% for feed in config.feed_filenames %} + {% if feed == "atom.xml" %} + + {% elif feed == "rss.xml" %} + + {% else %} + + {% endif %} + {% endfor %} + {% else %} + {# Older Zola versions #} + {% set feed_url = config.feed_filename | default(value="atom.xml") %} + + {% endif %} + {% endif %} + + {# CSS #} + {# Load subset of glyphs for header. Avoids flashing issue in Firefox #} + {% if config.extra.enable_subset %} + {% if config.extra.custom_subset == true %} + + {% elif lang == 'en' %} + + {% elif lang == 'es' %} + + {% endif %} + {% endif %} + + {# Define array of CSS files to load. main.css is always loaded. #} + {%- set stylesheets = [ "main.css" ] -%} + + {# Load extra CSS files from config.toml #} + {%- if config.extra.stylesheets -%} + {%- set stylesheets = stylesheets | concat(with=config.extra.stylesheets) -%} + {%- endif -%} + + {# Load extra CSS files from page metadata #} + {%- if page.extra.stylesheets -%} + {%- set stylesheets = stylesheets | concat(with=page.extra.stylesheets) -%} + {%- endif -%} + + {# Load extra CSS for custom skin #} + {%- if config.extra.skin -%} + {%- set stylesheets = stylesheets | concat(with='skins/' ~ config.extra.skin ~ '.css') -%} + {%- endif -%} + + {# Load all stylesheets #} + {%- for stylesheet in stylesheets %} + + {%- endfor %} + + + + {%- if config.extra.browser_theme_color and config.extra.browser_theme_color is iterable -%} + {# Handle array values: theme_color[0] for light mode, theme_color[1] for dark mode #} + + + {%- elif config.extra.browser_theme_color -%} + {# Handle single value #} + + {%- endif -%} + + {%- if page.description %} + + + {%- elif section.description %} + + + {%- elif page.summary %} + + + {%- else %} + + + {%- endif %} + + {% if is_404 %} + + {% endif %} + + + + + {# Image for social media sharing #} + {%- include "partials/social_media_images.html" -%} + + {# Add og:locale and hreflang tags for multilingual sites #} + {%- if config.languages | length > 0 and current_url %} + {%- include "partials/multilingual_tags.html" -%} + {%- else -%} + + {%- endif %} + + {# Set canonical URL #} + {%- if current_url -%} + {%- if page.extra.canonical_url or section.extra.canonical_url -%} + {%- set canonical_url = page.extra.canonical_url | default(value=section.extra.canonical_url) -%} + {%- elif config.extra.base_canonical_url -%} + {%- set canonical_url = current_url | replace(from=config.base_url, to=config.extra.base_canonical_url) -%} + {%- endif -%} + {%- endif -%} + + {# Add canonical URL, if set #} + {%- if canonical_url -%} + + + {%- elif current_url -%} + + {%- endif -%} + + + + {%- if config.extra.theme_switcher and config.extra.theme_switcher == true -%} + {# If JavaScript is disabled, hide the button. #} + + + + {%- endif -%} + + {%- if config.extra.analytics.service -%} + {%- include "partials/analytics.html" -%} + {%- endif -%} + + {# Socials #} + {%- if config.extra.fediverse_creator -%} + + {%- endif -%} + + {# Search #} + {%- if config.build_search_index -%} + {%- if config.search.index_format -%} + {%- set search_index_format = config.search.index_format -%} + {%- elif config.extra.index_format -%} + {# Necessary to support Zola 0.17.X, as it doesn't have access to config.search.index_format #} + {# See: https://github.com/getzola/zola/issues/2165 #} + {%- set search_index_format = config.extra.index_format -%} + {%- else -%} + {%- set search_index_format = "elasticlunr_json" -%} + {%- endif -%} + + {%- if search_index_format == "elasticlunr_javascript" -%} + + {%- endif -%} + + {# Main search script #} + + + {# Support correct stemming and stop word filtering in non-English search #} + {%- if lang != "en" -%} + + + {%- endif -%} + {%- endif -%} + + {# Users can optionally provide this template to add content to the head element. #} + {% include "tabi/extend_head.html" ignore missing %} + diff --git a/templates/partials/history_url.html b/templates/partials/history_url.html new file mode 100644 index 0000000..8327ca3 --- /dev/null +++ b/templates/partials/history_url.html @@ -0,0 +1,26 @@ +{%- set relative_path = page.relative_path -%} +{%- set repository_url = config.extra.remote_repository_url | trim_end_matches(pat='/') -%} +{%- set branch = config.extra.remote_repository_branch | default(value="main") -%} +{%- set git_platform = config.extra.remote_repository_git_platform | default(value="auto") -%} + +{# Auto-detect the git platform based on the URL#} +{%- if git_platform == "auto" %} + {%- if repository_url is containing("github.") -%} + {%- set git_platform = "github" -%} + {%- elif repository_url is containing("gitlab.") -%} + {%- set git_platform = "gitlab" -%} + {%- elif repository_url is matching("(gitea\.|codeberg\.)") -%} + {%- set git_platform = "gitea" -%} + {%- endif -%} +{%- endif -%} + +{# Generate the commit history URL based on the git platform #} +{%- if git_platform == "github" -%} + {{ repository_url ~ '/commits/' ~ branch ~ '/content/' }}{{ relative_path | urlencode }} +{%- elif git_platform == "gitlab" -%} + {{ repository_url ~ '/-/commits/' ~ branch ~ '/content/' }}{{ relative_path | urlencode }} +{%- elif git_platform in ["gitea", "codeberg"] -%} + {{ repository_url ~ '/commits/branch/' ~ branch ~ '/content/' }}{{ relative_path | urlencode }} +{%- else -%} + {{ throw(message="ERROR: Unknown, unsupported, or unspecified git platform. If you're using a custom domain, please specify the 'git_platform' in the config. If you think this is a bug, please report it: https://github.com/welpo/tabi/issues/new?assignees=&labels=bug&template=bug_report.md&title=Unsupported%20Git%20Platform%20Detected") }} +{%- endif -%} diff --git a/templates/partials/home_banner.html b/templates/partials/home_banner.html new file mode 100644 index 0000000..353757b --- /dev/null +++ b/templates/partials/home_banner.html @@ -0,0 +1,20 @@ +{%- set header = section.extra.header-%} + diff --git a/templates/partials/iine_button.html b/templates/partials/iine_button.html new file mode 100644 index 0000000..508fd3a --- /dev/null +++ b/templates/partials/iine_button.html @@ -0,0 +1,33 @@ +{% import "macros/settings.html" as macros_settings %} +{%- set button_icon = button_icon | default(value=macros_settings::evaluate_setting_priority(setting="iine_icon", page=page | default(value=""), section=section | default(value=""), default_global_value="heart")) -%} +{%- if config.extra.iine_unified_languages and lang != config.default_language -%} + {%- set unified_slug = page.path | replace(from='/' ~ lang ~ '/', to='/') -%} + {%- set slug = slug | default(value=unified_slug) -%} +{%- else -%} + {%- set slug = slug | default(value=page.path) -%} +{%- endif -%} +{%- if label -%} + {%- set final_label = label -%} +{%- elif language_strings -%} + {%- set final_label = macros_translate::translate(key="like_this_post", default="Like this post", language_strings=language_strings) -%} +{%- else -%} + {%- set final_label = "Like this post" -%} +{%- endif -%} + +{%- if button_icon == "heart" -%} + {%- set icon_display = "♥️" -%} +{%- elif button_icon == "thumbs_up" -%} + {%- set icon_display = "👍" -%} +{%- elif button_icon == "upvote" -%} + {%- set icon_display = "⬆️" -%} +{%- else -%} + {%- set icon_display = button_icon -%} +{%- endif -%} + +
    + + +
    diff --git a/templates/partials/language_switcher.html b/templates/partials/language_switcher.html new file mode 100644 index 0000000..83cf61f --- /dev/null +++ b/templates/partials/language_switcher.html @@ -0,0 +1,38 @@ +
  • + +
  • diff --git a/templates/partials/main_page_posts_list.html b/templates/partials/main_page_posts_list.html new file mode 100644 index 0000000..067e178 --- /dev/null +++ b/templates/partials/main_page_posts_list.html @@ -0,0 +1,61 @@ +{%- if paginator or extra_section -%} +
    +
    + {{ macros_page_header::page_header(title=section.title) }} +
    + + {# Check if both paginate_by and section_path are set #} + {%- set both_settings_set = paginator and extra_section -%} + {%- set paginator_has_no_pages = paginator and paginator.pages | length == 0 -%} + {%- set extra_section_has_pages = extra_section and extra_section.pages | length > 0 -%} + + {# Display warning if both settings are set #} + {%- if both_settings_set and paginator_has_no_pages and extra_section_has_pages -%} +
    +
    +
    + WARNING: Conflicting Configuration +

    + No posts are displayed due to conflicting settings in your _index.md: +

    +
      +
    • paginate_by is set, but there are no posts to paginate in the current section.
    • +
    • section_path is set, and posts are available in that section.
    • +
    +

    + Solution: Remove paginate_by from your _index.md. + To limit the number of displayed posts, use max_posts in the [extra] section instead. +

    +
    +
    + {%- endif -%} + + {# Get all posts for pinning if we're in root section with pagination #} + {%- if paginator and is_root_section -%} + {%- set root_section = get_section(path="_index.md") -%} + {%- set all_posts = root_section.pages -%} + {%- set pages = paginator.pages -%} + {%- elif paginator -%} + {%- set all_posts = paginator.pages -%} + {%- set pages = paginator.pages -%} + {%- else -%} + {%- set all_posts = extra_section.pages -%} + {%- set pages = extra_section.pages -%} + {%- endif -%} + + {% set max_posts = section.extra.max_posts | default(value=999999) %} + {{ macros_list_posts::list_posts( + posts=pages, + all_posts=all_posts, + max=max_posts, + language_strings=language_strings, + section_path=extra_section.path | default(value="blog"), + pinned_first=is_root_section, + current_page=paginator.current_index | default(value=1) + ) }} +
    + + {% if paginator and paginator.pages | length > 0 %} + {%- include "partials/paginate.html" -%} + {% endif %} +{%- endif -%} diff --git a/templates/partials/main_page_projects_list.html b/templates/partials/main_page_projects_list.html new file mode 100644 index 0000000..82f0637 --- /dev/null +++ b/templates/partials/main_page_projects_list.html @@ -0,0 +1,16 @@ +{% if section.extra.projects_path %} + {%- set projects_section = get_section(path=section.extra.projects_path) -%} + {%- if projects_section -%} + + {%- set show_pages = projects_section.pages -%} + {%- set max_projects = section.extra.max_projects | default(value=3) -%} + {%- include "partials/cards_pages.html" -%} + {%- endif -%} + {%- if show_pages | length > max_projects -%} + + {%- endif -%} +{% endif %} diff --git a/templates/partials/multilingual_tags.html b/templates/partials/multilingual_tags.html new file mode 100644 index 0000000..fe81e6e --- /dev/null +++ b/templates/partials/multilingual_tags.html @@ -0,0 +1,29 @@ +{%- if section.translations -%} + {%- set current_translations = section.translations -%} +{%- elif page.translations -%} + {%- set current_translations = page.translations -%} +{%- endif -%} + +{%- if current_translations -%} + + {%- for translation in current_translations -%} + {%- set lcode = translation.lang | default(value = config.default_language) -%} + + {#- Dynamically load the language strings for each language -#} + {%- set other_language_strings = load_data(path="i18n/" ~ lcode ~ ".toml", required=false) -%} + {%- if not other_language_strings -%} + {%- set other_language_strings = load_data(path="themes/tabi/i18n/" ~ lcode ~ ".toml", required=false) -%} + {%- endif -%} + + + {# Construct href for hreflang #} + {%- set href = translation.permalink -%} + {%- if lcode == config.default_language -%} + {%- set href = href | replace(from='/' ~ lang ~ '/', to = '/') -%} + {%- else -%} + {%- set href = href | replace(from='/' ~ lang ~ '/', to='/' ~ lcode ~ '/') -%} + {%- endif -%} + + {%- endfor -%} + +{%- endif -%} diff --git a/templates/partials/nav.html b/templates/partials/nav.html new file mode 100644 index 0000000..de55151 --- /dev/null +++ b/templates/partials/nav.html @@ -0,0 +1,60 @@ +
    + +
    diff --git a/templates/partials/paginate.html b/templates/partials/paginate.html new file mode 100644 index 0000000..6502af7 --- /dev/null +++ b/templates/partials/paginate.html @@ -0,0 +1,27 @@ +{% if paginator and paginator.number_pagers > 1 %} + +{% endif %} diff --git a/templates/partials/search_modal.html b/templates/partials/search_modal.html new file mode 100644 index 0000000..a3702d2 --- /dev/null +++ b/templates/partials/search_modal.html @@ -0,0 +1,31 @@ + diff --git a/templates/partials/social_media_images.html b/templates/partials/social_media_images.html new file mode 100644 index 0000000..d6bbcc7 --- /dev/null +++ b/templates/partials/social_media_images.html @@ -0,0 +1,50 @@ +{%- set social_media_card = macros_settings::evaluate_setting_priority(setting="social_media_card", page=page | default(value=""), section=section | default(value=""), default_global_value="") -%} +{% if social_media_card %} + {# Get base path from page/section #} + {% set base_path = "" %} + {% if section and section.path %} + {% set base_path = section.path | trim_end_matches(pat="/_index.md") %} + {% if base_path and not social_media_card is starting_with("/") %} + {% set base_path = base_path ~ "/" %} + {% endif %} + {% else %} + {% set base_path = page.colocated_path | default(value="") %} + {% endif %} + + {% set current_path = base_path ~ social_media_card | trim_start_matches(pat="/") %} + + {# Try parent path by removing the last directory component #} + {% set parent_path = base_path | split(pat="/") | slice(end=-2) | join(sep="/") %} + {% if parent_path and not social_media_card is starting_with("/") %} + {% set parent_path = parent_path ~ "/" %} + {% endif %} + {% set parent_relative_path = parent_path ~ social_media_card | trim_start_matches(pat="/") %} + + {# Check all possible locations #} + {%- set current_meta = get_image_metadata(path=current_path, allow_missing=true) -%} + {%- set parent_meta = get_image_metadata(path=parent_relative_path, allow_missing=true) -%} + {%- set absolute_meta = get_image_metadata(path=social_media_card, allow_missing=true) -%} + + {% if current_meta %} + {% set final_path = current_path %} + {% set meta = current_meta %} + {% elif parent_meta %} + {% set final_path = parent_relative_path %} + {% set meta = parent_meta %} + {% elif absolute_meta %} + {% set final_path = social_media_card %} + {% set meta = absolute_meta %} + {% else %} + {{ throw(message="Could not find social media card image. Tried: + 1. Current page path: '" ~ current_path ~ "' + 2. Parent page path: '" ~ parent_relative_path ~ "' + 3. Absolute path: '" ~ social_media_card ~ "' + Please ensure the file exists at one of these locations.") }} + {% endif %} + + + + + + +{% endif %} diff --git a/templates/partials/theme_switcher.html b/templates/partials/theme_switcher.html new file mode 100644 index 0000000..2e30f90 --- /dev/null +++ b/templates/partials/theme_switcher.html @@ -0,0 +1,31 @@ +
  • + {#- Create the localised strings for the title and aria-label attributes -#} + {%- set toggle_str = macros_translate::translate(key='toggle_mode', default='Toggle $MODE mode', language_strings=language_strings) -%} + {%- set dark_str = macros_translate::translate(key='dark', default='dark', language_strings=language_strings) -%} + {%- set light_str = macros_translate::translate(key='light', default='light', language_strings=language_strings) -%} + + {%- set combined_mode_str = dark_str ~ "/" ~ light_str -%} + {%- set title_label = toggle_str | replace(from="$MODE", to=combined_mode_str) -%} + {%- set aria_label = toggle_str | replace(from="$MODE", to=dark_str) -%} + +
    +
    + + {%- set reset_str = macros_translate::translate(key='reset_mode', default='Reset mode to default', language_strings=language_strings) -%} + + + +
  • diff --git a/templates/partials/title.html b/templates/partials/title.html new file mode 100644 index 0000000..de77d73 --- /dev/null +++ b/templates/partials/title.html @@ -0,0 +1,40 @@ +{#- Setup -#} +{% if not config.title %} +{{ throw(message="ERROR: No `title` set in `config.toml`. tabi requires a title to function.") }} +{% endif %} +{%- set prefix = config.title | safe -%} +{%- set custom_separator = config.extra.separator | default(value="•") -%} +{%- set separator = " " ~ custom_separator ~ " " -%} + +{#- Get the base path for the current language -#} +{%- if lang != config.default_language %} + {%- set base_path = "/" ~ lang ~ "/" %} +{%- else -%} + {%- set base_path = "/" %} +{%- endif %} + +{%- if current_path and current_path == base_path -%} + {%- set suffix = "" -%} + {%- set separator = "" -%} +{% elif title %} + {%- set suffix = title -%} +{% elif section.title -%} + {%- set suffix = section.title -%} +{% elif page.title %} + {%- set suffix = page.title -%} +{% elif term.name %} + {#- Individual tags -#} + {%- set suffix = term.name -%} +{% elif taxonomy.name %} + {#- List of tags -#} + {%- set suffix = macros_translate::translate(key=taxonomy.name, language_strings=language_strings) | capitalize -%} +{% else %} + {%- set suffix = "404" %} +{%- endif -%} + +{#- Return the final concatenated string -#} +{%- if config.extra.invert_title_order -%} + {{- suffix ~ separator ~ prefix -}} +{%- else -%} + {{- prefix ~ separator ~ suffix -}} +{%- endif -%} diff --git a/templates/partials/webmentions.html b/templates/partials/webmentions.html new file mode 100644 index 0000000..e579a04 --- /dev/null +++ b/templates/partials/webmentions.html @@ -0,0 +1,51 @@ +{# Incorporate webmention.io links and script into the page head. +1. Provide the link to the webmention data in the at webmention.io. +2. Link to the stylesheet for styling webmentions on a page. +3. Add and configure the javascript to fetch and display the webmentions collected at webmention.io. #} + + + +{# Calculate the configured data for the script, if any #} + +{% set script_data = "" %} + +{% if config.extra.webmentions.id %} +{% set script_data = script_data ~ "data-id=" ~ config.extra.webmentions.id %} +{% endif %} + +{% if config.extra.webmentions.page_url %} +{% set script_data = script_data ~ " data-page-url=" ~ config.extra.webmentions.page_url %} +{% endif %} + +{% if config.extra.webmentions.add_urls %} +{% set script_data = script_data ~ "data-add-urls=" ~ config.extra.webmentions.add_urls %} +{% endif %} + +{% if config.extra.webmentions.wordcount %} +{% set script_data = script_data ~ " data-wordcount=" ~ config.extra.webmentions.wordcount %} +{% endif %} + +{% if config.extra.webmentions.max_webmentions %} +{% set script_data = script_data ~ "data-max-webmentions=" ~ config.extra.webmentions.max_webmentions %} +{% endif %} + +{% if config.extra.webmentions.prevent_spoofing %} +{% set script_data = script_data ~ "data-prevent-spoofing=" ~ config.extra.webmentions.prevent_spoofing %} +{% endif %} + +{% if config.extra.webmentions.sort_by %} +{% set script_data = script_data ~ "data-sort-by=" ~ config.extra.webmentions.sort_by %} +{% endif %} + +{% if config.extra.webmentions.sort_dir %} +{% set script_data = script_data ~ "data-sort-dir=" ~ config.extra.webmentions.sort_dir %} +{% endif %} + +{% if config.extra.webmentions.comments_are_reactions %} +{% set script_data = script_data ~ " data-comments-are-reactions=" ~ config.extra.webmentions.comments_are_reactions %} +{% endif %} + + + +
    diff --git a/templates/section.html b/templates/section.html new file mode 100644 index 0000000..3f2af39 --- /dev/null +++ b/templates/section.html @@ -0,0 +1,57 @@ +{% extends "base.html" %} + +{% block main_content %} + +{# We'll only pin posts in the root section. #} +{# Right now both the main page and blog/ use the same `section.html` template. #} +{# To avoid using different templates, we do this. #} +{%- if lang == config.default_language -%} + {%- set expected_root = "/" -%} +{%- else -%} + {%- set expected_root = "/" ~ lang ~ "/" -%} +{%- endif -%} +{%- set is_root_section = current_path == expected_root -%} + +{%- set show_projects_first = section.extra.show_projects_first | default(value=false) -%} +{%- if show_projects_first -%} + {%- set first_section = "projects" -%} +{%- else -%} + {%- set first_section = "posts" -%} +{%- endif -%} + +{%- if section.extra.section_path or paginator and projects_path -%} + {%- set more_than_one_section_shown = true -%} +{%- endif -%} + +
    +{%- if config.extra.hcard %} + {%- include "partials/hcard.html" -%} +{% endif -%} +{%- if section.extra.header %} + {%- include "partials/home_banner.html" -%} +{%- elif section.content -%} +
    + {{ section.content | safe }} +
    +{% endif -%} + +{% if section.extra.section_path -%} + {% set extra_section = get_section(path=section.extra.section_path) %} +{% endif -%} + +{% if section.extra.section_path -%} + {% set path = section.extra.section_path | replace(from="/_index.md", to = "") %} +{% else -%} + {% set path = section.path %} +{% endif -%} + +{%- if show_projects_first -%} + {%- include "partials/main_page_projects_list.html" -%} + {%- include "partials/main_page_posts_list.html" -%} +{%- else -%} + {%- include "partials/main_page_posts_list.html" -%} + {%- include "partials/main_page_projects_list.html" -%} +{%- endif -%} +
    + +{% endblock main_content %} diff --git a/templates/series.html b/templates/series.html new file mode 100644 index 0000000..5a4cc0c --- /dev/null +++ b/templates/series.html @@ -0,0 +1,62 @@ +{% extends "base.html" %} + +{% block main_content %} + +{# Throw an error if the section is not flagged as a series. #} +{# This page would be displayed properly but it would become impossible for the series' child pages to reference their series. #} +{%- if "series" not in section.extra or not section.extra.series -%} + {{ throw(message="Section is not flagged as a series. Set `section.extra.series` to `true` if you want to use `series.html` template.") }} +{%- endif -%} + +
    +{%- if section.extra.header %} + {%- include "partials/home_banner.html" -%} +{% endif -%} + + {%- set show_jump = false -%} + {%- set show_jump_hierarchy = macros_settings::evaluate_setting_priority(setting="show_jump_to_posts", page=section) -%} + {%- if show_jump_hierarchy == "true" -%} + {%- set show_jump = true -%} + {%- elif show_jump_hierarchy != "false" -%} + {#- Default to true if the content is long and var is unset #} + {%- if section.content | length > 2000 -%} + {%- set show_jump = true -%} + {%- endif -%} + {%- endif -%} + + {%- if show_jump -%} + + {%- else -%} + {{ macros_page_header::page_header(title=section.title) }} + {%- endif -%} + +
    + {{ section.content | safe }} +
    + +
    +

    + {{ macros_translate::translate(key="all_posts", default="All posts", language_strings=language_strings) }} +

    + {%- if paginator %} + {%- set pages = paginator.pages -%} + {% else %} + {%- set pages = section.pages -%} + {% endif -%} + + {% set max_posts = section.extra.max_posts | default(value=999999) %} + {{ macros_list_posts::list_posts(posts=pages, max=max_posts, metadata="indexes", language_strings=language_strings, section_path=section.path, paginator=paginator | default(value="")) }} +
    + + {% if paginator %} + {%- include "partials/paginate.html" -%} + {% endif %} + +
    + +{%- include "partials/extra_features.html" -%} + +{% endblock main_content %} diff --git a/templates/shortcodes/add_src_to_code_block.html b/templates/shortcodes/add_src_to_code_block.html new file mode 100644 index 0000000..907e092 --- /dev/null +++ b/templates/shortcodes/add_src_to_code_block.html @@ -0,0 +1 @@ + diff --git a/templates/shortcodes/admonition.html b/templates/shortcodes/admonition.html new file mode 100644 index 0000000..3519527 --- /dev/null +++ b/templates/shortcodes/admonition.html @@ -0,0 +1,12 @@ +{%- set type = type | default(value="info") -%} +{%- set title = title | default(value=type | upper) -%} +{%- set icon = icon | default(value=type) -%} +{%- set text = text | default(value=body) -%} + +
    +
    +
    + {{ title | safe }} + {{ text | markdown | safe }} +
    +
    diff --git a/templates/shortcodes/aside.html b/templates/shortcodes/aside.html new file mode 100644 index 0000000..ca337f9 --- /dev/null +++ b/templates/shortcodes/aside.html @@ -0,0 +1,5 @@ +{%- set text = text | default(value=body) -%} + + diff --git a/templates/shortcodes/dimmable_image.html b/templates/shortcodes/dimmable_image.html new file mode 100644 index 0000000..a72720c --- /dev/null +++ b/templates/shortcodes/dimmable_image.html @@ -0,0 +1,31 @@ +{#- Determine image path based on whether the src is remote or local -#} +{%- if src is starting_with("http") or raw_path -%} + {%- set image_url = src -%} +{%- else -%} + {%- set colocated_path = page.colocated_path | default(value="") -%} + {%- set relative_path = colocated_path ~ src -%} + {%- set meta = get_image_metadata(path=relative_path, allow_missing=true) -%} + + {#- Fallback to absolute path if relative path doesn't work -#} + {%- if not meta -%} + {%- set meta = get_image_metadata(path=src, allow_missing=true) -%} + {%- set image_url = get_url(path=src, cachebust=true) -%} + {%- else -%} + {%- set image_url = get_url(path=relative_path, cachebust=true) -%} + {%- endif -%} +{%- endif -%} + +{%- set lazy_loading = lazy_loading | default(value=true) -%} + +{%- set class_list = "dimmable-image" -%} +{%- if inline -%} + {%- set class_list = class_list ~ " inline" -%} +{%- endif -%} + +{%- if full_width -%} +
    +{%- endif -%} + +{%- if full_width -%} +
    +{%- endif -%} diff --git a/templates/shortcodes/dual_theme_image.html b/templates/shortcodes/dual_theme_image.html new file mode 100644 index 0000000..5eadc09 --- /dev/null +++ b/templates/shortcodes/dual_theme_image.html @@ -0,0 +1,45 @@ +{%- set colocated_path = page.colocated_path | default(value="") -%} +{%- set lazy_loading = lazy_loading | default(value=true) -%} +{%- set inline = inline | default(value=false) -%} + +{%- set light_class_list = "img-light" -%} +{%- set dark_class_list = "img-dark" -%} +{%- if inline -%} + {%- set light_class_list = light_class_list ~ " inline" -%} + {%- set dark_class_list = dark_class_list ~ " inline" -%} +{%- endif -%} + +{# Handling for light mode image #} +{%- if light_src is starting_with("http") or raw_path -%} + {%- set light_image_url = light_src -%} +{%- else -%} + {%- set relative_light_path = colocated_path ~ light_src -%} + {%- set light_meta = get_image_metadata(path=relative_light_path, allow_missing=true) -%} + {%- if not light_meta -%} + {%- set light_image_url = get_url(path=light_src, cachebust=true) -%} + {%- else -%} + {%- set light_image_url = get_url(path=relative_light_path, cachebust=true) -%} + {%- endif -%} +{%- endif -%} + +{# Handling for dark mode image #} +{%- if dark_src is starting_with("http") or raw_path -%} + {%- set dark_image_url = dark_src -%} +{%- else -%} + {%- set relative_dark_path = colocated_path ~ dark_src -%} + {%- set dark_meta = get_image_metadata(path=relative_dark_path, allow_missing=true) -%} + {%- if not dark_meta -%} + {%- set dark_image_url = get_url(path=dark_src, cachebust=true) -%} + {%- else -%} + {%- set dark_image_url = get_url(path=relative_dark_path, cachebust=true) -%} + {%- endif -%} +{%- endif -%} + +{%- if full_width -%} +
    +{%- endif -%} + + +{%- if full_width -%} +
    +{%- endif -%} diff --git a/templates/shortcodes/force_text_direction.html b/templates/shortcodes/force_text_direction.html new file mode 100644 index 0000000..79d9697 --- /dev/null +++ b/templates/shortcodes/force_text_direction.html @@ -0,0 +1,5 @@ +{%- set direction = direction | default(value="ltr") -%} + +
    + {{ body | markdown | safe }} +
    diff --git a/templates/shortcodes/full_width_image.html b/templates/shortcodes/full_width_image.html new file mode 100644 index 0000000..a50bf10 --- /dev/null +++ b/templates/shortcodes/full_width_image.html @@ -0,0 +1,22 @@ +{#- Set paths based on whether the src is remote or local -#} +{%- if src is starting_with("http") or raw_path -%} + {%- set image_url = src -%} +{%- else -%} + {%- set colocated_path = page.colocated_path | default(value="") -%} + {%- set relative_path = colocated_path ~ src -%} + {%- set meta = get_image_metadata(path=relative_path, allow_missing=true) -%} + + {#- Fallback to absolute path if relative path doesn't work -#} + {%- if not meta -%} + {%- set meta = get_image_metadata(path=src, allow_missing=true) -%} + {%- set image_url = get_url(path=src, cachebust=true) -%} + {%- else %} + {%- set image_url = get_url(path=relative_path, cachebust=true) -%} + {%- endif -%} +{%- endif -%} + +{%- set lazy_loading = lazy_loading | default(value=true) -%} + +
    + +
    diff --git a/templates/shortcodes/iine.html b/templates/shortcodes/iine.html new file mode 100644 index 0000000..d37211d --- /dev/null +++ b/templates/shortcodes/iine.html @@ -0,0 +1,5 @@ +{% set button_icon = icon | default(value="heart") %} +{% set label = label | default(value="Like this post") %} +{% set slug = slug | default(value=page.path) %} + +{% include "partials/iine_button.html" %} diff --git a/templates/shortcodes/image_hover.html b/templates/shortcodes/image_hover.html new file mode 100644 index 0000000..443329b --- /dev/null +++ b/templates/shortcodes/image_hover.html @@ -0,0 +1,50 @@ +{%- set colocated_path = page.colocated_path | default(value="") -%} +{%- set lazy_loading = lazy_loading | default(value=true) -%} +{%- set inline = inline | default(value=false) -%} + +{#- Determine the tag for container elements -#} +{#- Necessary for inline images -#} +{%- set tag = "div" -%} +{%- if inline -%} + {%- set tag = "span" -%} +{%- endif -%} + +{%- set img_class_list = "" -%} +{%- if inline -%} + {%- set img_class_list = img_class_list ~ " inline" -%} +{%- endif -%} + +{#- Direct or relative URL handling for default image -#} +{%- if default_src is starting_with("http") or raw_path -%} + {%- set default_image_url = default_src -%} +{%- else -%} + {%- set relative_default_path = colocated_path ~ default_src -%} + {%- set default_meta = get_image_metadata(path=relative_default_path, allow_missing=true) -%} + {%- if not default_meta -%} + {%- set default_image_url = get_url(path=default_src, cachebust=true) -%} + {%- else -%} + {%- set default_image_url = get_url(path=relative_default_path, cachebust=true) -%} + {%- endif -%} +{%- endif -%} + +{#- Direct or relative URL handling for hovered image -#} +{%- if hovered_src is starting_with("http") or raw_path -%} + {%- set hovered_image_url = hovered_src -%} +{%- else -%} + {%- set relative_hovered_path = colocated_path ~ hovered_src -%} + {%- set hovered_meta = get_image_metadata(path=relative_hovered_path, allow_missing=true) -%} + {%- if not hovered_meta -%} + {%- set hovered_image_url = get_url(path=hovered_src, cachebust=true) -%} + {%- else -%} + {%- set hovered_image_url = get_url(path=relative_hovered_path, cachebust=true) -%} + {%- endif -%} +{%- endif -%} + +<{{ tag }} class="image-hover-container{% if full_width %} full-width{% endif %}"> + <{{ tag }} class="image-default"> + {{ default_alt }} + + <{{ tag }} class="image-hovered"> + {{ hovered_alt }} + + diff --git a/templates/shortcodes/image_toggler.html b/templates/shortcodes/image_toggler.html new file mode 100644 index 0000000..991d5f5 --- /dev/null +++ b/templates/shortcodes/image_toggler.html @@ -0,0 +1,57 @@ +{# The `random_id` ensures that each instance of the shortcode has a "unique" id #} +{# allowing individual interactive elements (like toggles) to function correctly. #} +{# This avoids conflicts when multiple instances of the shortcode are used. #} +{%- set random_id = get_random(end=100000) -%} +{%- set colocated_path = page.colocated_path | default(value="") -%} +{%- set lazy_loading = lazy_loading | default(value=true) -%} +{%- set inline = inline | default(value=false) -%} + +{#- Determine the class for the images -#} +{#- Necessary for inline images -#} +{%- set tag = "div" -%} +{%- if inline -%} + {%- set tag = "span" -%} +{%- endif -%} + +{%- set img_class_list = "" -%} +{%- if inline -%} + {%- set img_class_list = img_class_list ~ " inline" -%} +{%- endif -%} + +{# Direct or relative URL handling for default image #} +{%- if default_src is starting_with("http") or raw_path -%} + {%- set default_image_url = default_src -%} +{%- else -%} + {%- set relative_default_path = colocated_path ~ default_src -%} + {%- set default_meta = get_image_metadata(path=relative_default_path, allow_missing=true) -%} + {%- if not default_meta -%} + {%- set default_image_url = get_url(path=default_src, cachebust=true) -%} + {%- else -%} + {%- set default_image_url = get_url(path=relative_default_path, cachebust=true) -%} + {%- endif -%} +{%- endif -%} + +{# Direct or relative URL handling for toggled image #} +{%- if toggled_src is starting_with("http") or raw_path -%} + {%- set toggled_image_url = toggled_src -%} +{%- else -%} + {%- set relative_toggled_path = colocated_path ~ toggled_src -%} + {%- set toggled_meta = get_image_metadata(path=relative_toggled_path, allow_missing=true) -%} + {%- if not toggled_meta -%} + {%- set toggled_image_url = get_url(path=toggled_src, cachebust=true) -%} + {%- else -%} + {%- set toggled_image_url = get_url(path=relative_toggled_path, cachebust=true) -%} + {%- endif -%} +{%- endif -%} + +<{{ tag }} class="image-toggler-container {% if full_width %}full-width{% endif %}"> + + + diff --git a/templates/shortcodes/invertible_image.html b/templates/shortcodes/invertible_image.html new file mode 100644 index 0000000..0e3c920 --- /dev/null +++ b/templates/shortcodes/invertible_image.html @@ -0,0 +1,32 @@ +{#- Determine if src is a remote URL or a local path -#} +{%- if src is starting_with("http") or raw_path -%} + {%- set image_url = src -%} +{%- else -%} + {%- set colocated_path = page.colocated_path | default(value="") -%} + {%- set relative_path = colocated_path ~ src -%} + {%- set meta = get_image_metadata(path=relative_path, allow_missing=true) -%} + + {#- Fallback to absolute path if relative path doesn't work -#} + {%- if not meta -%} + {%- set meta = get_image_metadata(path=src, allow_missing=true) -%} + {%- set image_url = get_url(path=src, cachebust=true) -%} + {%- else %} + {%- set image_url = get_url(path=relative_path, cachebust=true) -%} + {%- endif -%} +{%- endif -%} + +{%- set lazy_loading = lazy_loading | default(value=true) -%} +{%- set inline = inline | default(value=false) -%} + +{%- set class_list = "invertible-image" -%} +{%- if inline -%} + {%- set class_list = class_list ~ " inline" -%} +{%- endif -%} + +{%- if full_width -%} +
    +{%- endif -%} + +{%- if full_width -%} +
    +{%- endif -%} diff --git a/templates/shortcodes/mermaid.html b/templates/shortcodes/mermaid.html new file mode 100644 index 0000000..88bbdc4 --- /dev/null +++ b/templates/shortcodes/mermaid.html @@ -0,0 +1,8 @@ +{% set invertible = invertible | default(value=true) %} +{% set full_width = full_width | default(value=false) %} + +
    +    {{ body | safe }}
    +
    diff --git a/templates/shortcodes/multilingual_quote.html b/templates/shortcodes/multilingual_quote.html new file mode 100644 index 0000000..7ea9849 --- /dev/null +++ b/templates/shortcodes/multilingual_quote.html @@ -0,0 +1,37 @@ +{%- import "macros/translate.html" as macros_translate -%} +{# Load internationalisation data #} +{%- set language_strings = load_data(path="i18n/" ~ lang ~ '.toml', required=false) -%} +{%- if not language_strings -%} + {%- set language_strings = load_data(path="themes/tabi/i18n/" ~ lang ~ ".toml", required=false) -%} +{%- endif -%} + +{%- set open_quote = macros_translate::translate(key="open_quotation_mark", default="“", language_strings=language_strings) -%} +{%- set close_quote = macros_translate::translate(key="close_quotation_mark", default="”", language_strings=language_strings) -%} + +{#- The `random_id` ensures that each instance of the shortcode has a "unique" id -#} +{#- allowing individual interactive elements (like toggles) to function correctly. -#} +{#- This avoids conflicts when multiple instances of the shortcode are used. -#} +{#- More context: https://github.com/welpo/tabi/issues/82 -#} +{%- set random_id = get_random(end=100000) -%} + +
    + +
    +
    +
    +

    {{ open_quote ~ translated ~ close_quote }}

    +

    {% if author %}— {{ author | safe }}{% endif %}

    +
    +
    +
    +
    +

    {{ open_quote ~ original ~ close_quote }}

    +

    {% if author %}— {{ author | safe }}{% endif %}

    +
    +
    +
    +
    diff --git a/templates/shortcodes/references.html b/templates/shortcodes/references.html new file mode 100644 index 0000000..1894479 --- /dev/null +++ b/templates/shortcodes/references.html @@ -0,0 +1,3 @@ +
    + {{ body | markdown | safe }} +
    diff --git a/templates/shortcodes/remote_text.html b/templates/shortcodes/remote_text.html new file mode 100644 index 0000000..70fd33a --- /dev/null +++ b/templates/shortcodes/remote_text.html @@ -0,0 +1,30 @@ +{%- set start = start | default(value=1) -%} +{%- set end = end | default(value=0) -%} + +{#- load_data uses different arguments based on whether it's a remote or local file -#} +{%- if src is starting_with("http") -%} + {%- set response = load_data(url=src, format="plain") -%} +{%- else -%} + {#- Try to load the file from a relative path -#} + {%- set colocated_path = page.colocated_path | default(value="") -%} + {%- set relative_path = colocated_path ~ src -%} + {%- set response = load_data(path=relative_path, format="plain", required=false) -%} + {#- If relative path fails, try absolute path -#} + {%- if not response -%} + {%- set response = load_data(path=src, format="plain") -%} + {%- endif -%} +{%- endif -%} + +{%- set lines = response | trim_end | split(pat="\n") -%} + +{%- if start > 0 -%} + {%- set start = start - 1 -%} +{%- endif -%} + +{%- if end == 0 or end > lines | length -%} + {%- set end = lines | length -%} +{%- endif -%} + +{%- set lines = lines | slice(start=start, end=end) -%} + +{{- lines | join(sep="\n") | safe -}} diff --git a/templates/shortcodes/spoiler.html b/templates/shortcodes/spoiler.html new file mode 100644 index 0000000..ff9e695 --- /dev/null +++ b/templates/shortcodes/spoiler.html @@ -0,0 +1,13 @@ +{# The `random_id` ensures that each instance of the shortcode has a "unique" id #} +{# allowing individual interactive elements (like toggles) to function correctly. #} +{# This avoids conflicts when multiple instances of the shortcode are used. #} +{# More context: https://github.com/welpo/tabi/issues/82 #} +{%- set random_id = get_random(end=100000) -%} +{%- set fixed_blur = fixed_blur | default(value=false) -%} + + diff --git a/templates/shortcodes/toc.html b/templates/shortcodes/toc.html new file mode 100644 index 0000000..8756586 --- /dev/null +++ b/templates/shortcodes/toc.html @@ -0,0 +1,2 @@ +{# Inserts special string to add the Table of Contents anywhere on a post #} + diff --git a/templates/shortcodes/wide_container.html b/templates/shortcodes/wide_container.html new file mode 100644 index 0000000..6268e63 --- /dev/null +++ b/templates/shortcodes/wide_container.html @@ -0,0 +1,3 @@ +
    + {{ body | markdown | safe }} +
    diff --git a/templates/sitemap.xml b/templates/sitemap.xml new file mode 100644 index 0000000..480759f --- /dev/null +++ b/templates/sitemap.xml @@ -0,0 +1,12 @@ + + + + {%- for sitemap_entry in entries %} + + {{ sitemap_entry.permalink | escape_xml | safe }} + {%- if sitemap_entry.updated %} + {{ sitemap_entry.updated }} + {%- endif %} + + {%- endfor %} + diff --git a/templates/tags/list.html b/templates/tags/list.html new file mode 100644 index 0000000..7b5e468 --- /dev/null +++ b/templates/tags/list.html @@ -0,0 +1,40 @@ +{% extends "index.html" %} + +{% block main_content %} + +{%- set title = macros_translate::translate(key="all_tags", default="All tags", language_strings=language_strings) -%} + +{{ macros_page_header::page_header(title=title)}} + +{% set tag_count = terms | length %} +{% if config.extra.tag_sorting == "frequency" %} + {% set terms = terms | sort(attribute="pages") | reverse %} +{% elif config.extra.tag_sorting != "name" %} + {{ throw (message="Invalid tag_sorting option: " ~ config.extra.tag_sorting ~ ". Valid options are 'name' and 'frequency'.") }} +{% endif %} +
    +
      + {%- for term in terms -%} +
    • + {%- set number_of_posts = term.pages | length -%} + {% if config.extra.compact_tags %} + {# Shows the number of posts per tag as a superscript #} + + {{ term.name }} + {{ number_of_posts }} + {% else %} + + {{ term.name }} + + {{- macros_translate::translate(key="posts", number=number_of_posts, default="$NUMBER posts", language_strings=language_strings) -}} + {% endif %} +
    • + {%- endfor -%} +
    +
    + +{% endblock main_content %} diff --git a/templates/tags/single.html b/templates/tags/single.html new file mode 100644 index 0000000..2f25fd2 --- /dev/null +++ b/templates/tags/single.html @@ -0,0 +1,22 @@ +{% extends "index.html" %} + +{% block main_content %} + +{#- Feed icon -#} +{%- set generate_feed = feed_utils::get_generate_feed() == "true" -%} +{%- set feed_url = feed_utils::get_feed_url() -%} +{%- set feed_pre_conditions = generate_feed and feed_url and taxonomy.feed -%} +{%- set show_feed_icon = feed_pre_conditions and term.pages | filter(attribute="date") -%} + +{{ macros_page_header::page_header(title=term.name, show_feed_icon=show_feed_icon) }} + +{% set max = section.extra.max_posts | default(value=999999) %} +{{ macros_list_posts::list_posts(posts=term.pages, max=max, language_strings=language_strings) }} + + + +{% endblock main_content %} diff --git a/templates/taxonomy_list.html b/templates/taxonomy_list.html new file mode 100644 index 0000000..b13e1b9 --- /dev/null +++ b/templates/taxonomy_list.html @@ -0,0 +1,40 @@ +{% extends "index.html" %} + +{% block main_content %} + +{%- set title = macros_translate::translate(key=taxonomy.name, default=taxonomy.name, language_strings=language_strings) -%} + +{{ macros_page_header::page_header(title=title)}} + +{% set tag_count = terms | length %} +{% if config.extra.tag_sorting == "frequency" %} + {% set terms = terms | sort(attribute="pages") | reverse %} +{% elif config.extra.tag_sorting != "name" %} + {{ throw (message="Invalid tag_sorting option: " ~ config.extra.tag_sorting ~ ". Valid options are 'name' and 'frequency'.") }} +{% endif %} +
    +
      + {%- for term in terms -%} +
    • + {%- set number_of_posts = term.pages | length -%} + {% if config.extra.compact_tags %} + {# Shows the number of posts per tag as a superscript #} + + {{ term.name }} + {{ number_of_posts }} + {% else %} + + {{ term.name }} + + {{- macros_translate::translate(key="posts", number=number_of_posts, default="$NUMBER posts", language_strings=language_strings) -}} + {% endif %} +
    • + {%- endfor -%} +
    +
    + +{% endblock main_content %} diff --git a/templates/taxonomy_single.html b/templates/taxonomy_single.html new file mode 100644 index 0000000..ff09a3b --- /dev/null +++ b/templates/taxonomy_single.html @@ -0,0 +1,22 @@ +{% extends "index.html" %} + +{% block main_content %} + +{#- Feed icon -#} +{%- set generate_feed = feed_utils::get_generate_feed() == "true" -%} +{%- set feed_url = feed_utils::get_feed_url() -%} +{%- set feed_pre_conditions = generate_feed and feed_url and taxonomy.feed -%} +{%- set show_feed_icon = feed_pre_conditions and term.pages | filter(attribute="date") | length > 0 -%} + +{{ macros_page_header::page_header(title=term.name, show_feed_icon=show_feed_icon) }} + +{% set max = section.extra.max_posts | default(value=999999) %} +{{ macros_list_posts::list_posts(posts=term.pages, max=max, language_strings=language_strings) }} + + + +{% endblock main_content %} -- cgit v1.2.3