{# Recursive macro to render a thread node and its children #} {% macro render_thread_node(node, depth=0, parent_anchor=None) %} {% set max_indent = 5 %} {% set indent_depth = [depth, max_indent] | min %} {% set current_anchor = get_anchor_id(node) %}
{% if node.reaction_type.value == 'webmention' %} {{ render_webmention(node.item, node.identity, parent_anchor) }} {% elif node.reaction_type.value == 'ap_interaction' %} {{ render_ap_interaction(node.item, node.identity, parent_anchor) }} {% elif node.reaction_type.value == 'author_reply' %} {{ render_author_reply(node.item, parent_anchor) }} {% endif %} {% for child in node.children %} {{ render_thread_node(child, depth + 1, current_anchor) }} {% endfor %}
{% endmacro %} {# Helper to get anchor ID for a node #} {% macro get_anchor_id(node) %} {%- if node.reaction_type.value == 'webmention' -%} wm-{{ node.identity | hash_id }} {%- elif node.reaction_type.value == 'ap_interaction' -%} ap-{{ node.identity | hash_id }} {%- elif node.reaction_type.value == 'author_reply' -%} reply-{{ node.item.full_url | hash_id }} {%- endif -%} {% endmacro %} {# Render a single Webmention #} {% macro render_webmention(wm, identity, parent_anchor=None) %} {% set anchor_id = 'wm-' ~ (identity | hash_id) %} {% set source = wm.source or wm.author_url %} {% set source_url = ('https://' ~ utils.hostname(source)) if source and not source.startswith('https://') else source %} {% set source_hostname = utils.hostname(source_url) %} {% set author_name = wm.author_name or 'Anonymous' %}
{% if wm.author_photo %} {% else %} {% include 'icons/user.html' %} {% endif %}
{% if wm.author_url %} {{ author_name }} {% else %} {{ author_name }} {% endif %} {% if wm.mention_type and wm.mention_type.value != 'mention' and wm.mention_type.value != 'reply' %} {% if wm.mention_type.value == 'like' %} {% elif wm.mention_type.value == 'reblog' %} 🔁 {% elif wm.mention_type.value == 'quote' %} 🗣️ {% elif wm.mention_type.value == 'webmention' %} 🔗 {% elif wm.mention_type.value == 'author_reply' %} >✍️ {% endif %} {% endif %} {% if parent_anchor %} {% endif %} {% if wm.published %} {% endif %}
{% if source_url %} {% endif %}
{% if wm.title and wm.title != wm.excerpt %}
{{ wm.title }}
{% endif %} {% if wm.content %}
{{ wm.content | safe }}
{% if wm.content|length > 1000 %} {% endif %} {% elif wm.excerpt %}
{{ wm.excerpt }}
{% if wm.excerpt|length > 1000 %} {% endif %} {% endif %} {# Render mf2 metadata if present #} {% if wm.metadata %} {% set metadata = wm.metadata | fromjson %} {% set mf2 = (metadata.get("mf2") if metadata is mapping else None) | fromjson %} {% if mf2 and mf2 is mapping %} {% set bookmark_of = mf2.get("bookmark_of") or [] %} {% set follow_of = mf2.get("follow_of") or [] %} {% set rsvp = mf2.get("rsvp") %} {% set location = mf2.get("location") %} {% set category = mf2.get("category") or [] %} {% set syndication = mf2.get("syndication") or [] %} {% set photo = mf2.get("photo") or mf2.get("photo_url") or [] %} {% set video = mf2.get("video") or mf2.get("video_url") or [] %} {% set audio = mf2.get("audio") or mf2.get("audio_url") or [] %}
{% if bookmark_of %}
🔖 {% for url in bookmark_of %} {% set bmurl = url | safe_url %} {% if bmurl %} {{ utils.hostname(bmurl) or bmurl }}{% if not loop.last %}, {% endif %} {% endif %} {% endfor %}
{% endif %} {% if follow_of %}
👋 {% for url in follow_of %} {% set furl = url | safe_url %} {% if furl %} {{ utils.hostname(furl) or furl }}{% if not loop.last %}, {% endif %} {% endif %} {% endfor %}
{% endif %} {% if rsvp %}
📅 {{ rsvp }}
{% endif %} {% if location %}
📍 {{ location }}
{% endif %} {% if category %}
🏷️ {% for c in category %} {{ c }}{% if not loop.last %}, {% endif %} {% endfor %}
{% endif %} {% if syndication %}
🔗 {% for url in syndication %} {% set surl = url | safe_url %} {% if surl %} {{ utils.hostname(surl) or surl }}{% if not loop.last %}, {% endif %} {% endif %} {% endfor %}
{% endif %} {% if photo %}
{% for url in photo %} {% set purl = url | safe_url %} {% if purl %} {% endif %} {% endfor %}
{% endif %} {% if video %}
{% for url in video %} {% set vurl = url | safe_url %} {% if vurl %} {% endif %} {% endfor %}
{% endif %} {% if audio %}
{% for url in audio %} {% set aurl = url | safe_url %} {% if aurl %} {% endif %} {% endfor %}
{% endif %}
{% endif %} {% endif %}
{% endmacro %} {# Render a single AP interaction #} {% macro render_ap_interaction(interaction, identity, parent_anchor=None) %} {% set anchor_id = 'ap-' ~ (identity | hash_id) %}
{% if interaction.author_photo %} {% else %} {% include 'icons/user.html' %} {% endif %}
{% if interaction.author_url %} {{ interaction.author_name or interaction.source_actor_id }} {% else %} {{ interaction.author_name or interaction.source_actor_id }} {% endif %} {% if interaction.interaction_type.value != 'reply' and interaction.interaction_type.value != 'mention' %} {% if interaction.interaction_type.value == 'like' %} {% elif interaction.interaction_type.value == 'boost' %} 🔁 {% elif interaction.interaction_type.value == 'quote' %} 🗣️ {% elif interaction.interaction_type.value == 'webmention' %} 🔗 {% elif interaction.interaction_type.value == 'author_reply' %} >✍️ {% endif %} {% endif %} {% if parent_anchor %} {% endif %} {% if interaction.published %} {% endif %}
{% if interaction.author_url %} {% endif %}
{% if interaction.content %}
{{ interaction.content | safe }}
{% if interaction.content|length > 1000 %} {% endif %} {% endif %}
{% endmacro %} {# Render an author reply #} {% macro render_author_reply(reply, parent_anchor=None) %} {% set anchor_id = 'reply-' ~ (reply.full_url | hash_id) %}
{% if reply.author_photo %} {% else %} {% include 'icons/user.html' %} {% endif %}
{% if reply.author_url %} {{ reply.author or 'Author' }} {% else %} {{ reply.author or 'Author' }} {% endif %} Author {% if parent_anchor %} {% endif %} {% if reply.published %} {% endif %}
{% if reply.title and reply.title != reply.slug %}
{{ reply.title }}
{% endif %}
{{ reply.content_html | safe }}
{% if reply.content_html|length > 1000 %} {% endif %}
{% endmacro %} {# Main reactions section #} {% if reactions_tree %}

Reactions

{% if reactions_counts and reactions_counts.total > 0 %}
{% if reactions_counts.likes %}⭐ {{ reactions_counts.likes }}{% endif %} {% if reactions_counts.boosts %}🔁 {{ reactions_counts.boosts }}{% endif %} {% if reactions_counts.replies %}💬 {{ reactions_counts.replies }}{% endif %} {% if reactions_counts.quotes %}🗣️ {{ reactions_counts.quotes }}{% endif %} {% if reactions_counts.mentions %}📣 {{ reactions_counts.mentions }}{% endif %} {% if reactions_counts.webmentions %}🔗 {{ reactions_counts.webmentions }}{% endif %} {% if reactions_counts.author_replies %}✍️ {{ reactions_counts.author_replies }}{% endif %}
{% endif %}
{% for node in reactions_tree %} {{ render_thread_node(node, 0) }} {% endfor %}
{% endif %}