fix: prioritize homepage builder identity across widgets
This commit is contained in:
@@ -5,20 +5,20 @@
|
||||
Include in sidebar widgets, author cards, etc.
|
||||
#}
|
||||
{% set id = homepageConfig.identity if (homepageConfig and homepageConfig.identity) else {} %}
|
||||
{% set authorName = id.name or site.author.name %}
|
||||
{% set authorAvatar = id.avatar or site.author.avatar %}
|
||||
{% set authorTitle = id.title or site.author.title %}
|
||||
{% set authorBio = id.bio or site.author.bio %}
|
||||
{% set authorUrl = id.url or site.author.url %}
|
||||
{% set authorPronoun = id.pronoun or site.author.pronoun %}
|
||||
{% set authorLocality = id.locality or site.author.locality %}
|
||||
{% set authorCountry = id.country or site.author.country %}
|
||||
{% set authorLocation = site.author.location %}
|
||||
{% set authorOrg = id.org or site.author.org %}
|
||||
{% set authorEmail = id.email or site.author.email %}
|
||||
{% set authorKeyUrl = id.keyUrl or site.author.keyUrl %}
|
||||
{% set authorCategories = id.categories if (id.categories and id.categories.length) else site.author.categories %}
|
||||
{% set socialLinks = id.social if (id.social and id.social.length) else site.social %}
|
||||
{% set authorName = id.name if (id.name is defined) else site.author.name %}
|
||||
{% set authorAvatar = id.avatar if (id.avatar is defined) else site.author.avatar %}
|
||||
{% set authorTitle = id.title if (id.title is defined) else site.author.title %}
|
||||
{% set authorBio = id.bio if (id.bio is defined) else site.author.bio %}
|
||||
{% set authorUrl = id.url if (id.url is defined and id.url) else site.author.url %}
|
||||
{% set authorPronoun = id.pronoun if (id.pronoun is defined) else site.author.pronoun %}
|
||||
{% set authorLocality = id.locality if (id.locality is defined) else site.author.locality %}
|
||||
{% set authorCountry = id.country if (id.country is defined) else site.author.country %}
|
||||
{% set authorLocation = id.location if (id.location is defined) else site.author.location %}
|
||||
{% set authorOrg = id.org if (id.org is defined) else site.author.org %}
|
||||
{% set authorEmail = id.email if (id.email is defined) else site.author.email %}
|
||||
{% set authorKeyUrl = id.keyUrl if (id.keyUrl is defined) else site.author.keyUrl %}
|
||||
{% set authorCategories = id.categories if (id.categories is defined) else site.author.categories %}
|
||||
{% set socialLinks = id.social if (id.social is defined) else site.social %}
|
||||
|
||||
<div class="h-card p-author" itemscope itemtype="http://schema.org/Person">
|
||||
{# Hidden u-photo for reliable microformat parsing (some parsers struggle with img inside links) #}
|
||||
@@ -43,7 +43,9 @@
|
||||
{% if authorPronoun %}
|
||||
<span class="p-pronoun text-xs text-surface-600 dark:text-surface-400">({{ authorPronoun }})</span>
|
||||
{% endif %}
|
||||
{% if authorTitle %}
|
||||
<p class="p-job-title text-sm text-surface-600 dark:text-surface-400" itemprop="jobTitle">{{ authorTitle }}</p>
|
||||
{% endif %}
|
||||
{# Structured address #}
|
||||
<p class="p-adr h-adr text-sm text-surface-600 dark:text-surface-400" itemprop="address" itemscope itemtype="http://schema.org/PostalAddress">
|
||||
{% if authorLocality %}
|
||||
@@ -61,7 +63,9 @@
|
||||
</div>
|
||||
|
||||
{# Bio #}
|
||||
{% if authorBio %}
|
||||
<p class="p-note mt-3 text-sm text-surface-700 dark:text-surface-300" itemprop="description">{{ authorBio }}</p>
|
||||
{% endif %}
|
||||
|
||||
{# Organization #}
|
||||
{% if authorOrg %}
|
||||
|
||||
@@ -1,30 +1,43 @@
|
||||
{# Author Compact Card - h-card microformat (compact version for blog sidebars) #}
|
||||
{% set id = homepageConfig.identity if (homepageConfig and homepageConfig.identity) else {} %}
|
||||
{% set authorName = id.name if (id.name is defined) else site.author.name %}
|
||||
{% set authorAvatar = id.avatar if (id.avatar is defined) else site.author.avatar %}
|
||||
{% set authorTitle = id.title if (id.title is defined) else site.author.title %}
|
||||
{% set authorUrl = id.url if (id.url is defined and id.url) else site.author.url %}
|
||||
{% set authorLocality = id.locality if (id.locality is defined) else site.author.locality %}
|
||||
{% set authorCountry = id.country if (id.country is defined) else site.author.country %}
|
||||
{% set authorBio = id.bio if (id.bio is defined) else site.author.bio %}
|
||||
{% set authorEmail = id.email if (id.email is defined) else site.author.email %}
|
||||
{% set authorOrg = id.org if (id.org is defined) else site.author.org %}
|
||||
|
||||
<is-land on:visible>
|
||||
<div class="widget">
|
||||
<div class="h-card p-author flex items-center gap-3">
|
||||
{# Hidden u-photo for reliable microformat parsing #}
|
||||
<data class="u-photo hidden" value="{{ site.author.avatar }}"></data>
|
||||
<a href="{{ site.author.url }}" class="u-url u-uid" rel="me" itemprop="url" aria-label="{{ site.author.name }}">
|
||||
<data class="u-photo hidden" value="{{ authorAvatar }}"></data>
|
||||
<a href="{{ authorUrl }}" class="u-url u-uid" rel="me" itemprop="url" aria-label="{{ authorName }}">
|
||||
<img
|
||||
src="{{ site.author.avatar }}"
|
||||
src="{{ authorAvatar }}"
|
||||
alt=""
|
||||
class="w-12 h-12 rounded-full object-cover shadow-lg"
|
||||
loading="lazy"
|
||||
>
|
||||
</a>
|
||||
<div>
|
||||
<a href="{{ site.author.url }}" class="u-url p-name font-medium text-surface-900 dark:text-surface-100 hover:text-accent-600 dark:hover:text-accent-400 transition-colors">
|
||||
{{ site.author.name }}
|
||||
<a href="{{ authorUrl }}" class="u-url p-name font-medium text-surface-900 dark:text-surface-100 hover:text-accent-600 dark:hover:text-accent-400 transition-colors">
|
||||
{{ authorName }}
|
||||
</a>
|
||||
<p class="p-job-title text-xs text-surface-600 dark:text-surface-400">{{ site.author.title }}</p>
|
||||
{% if site.author.locality %}
|
||||
<p class="p-locality text-xs text-surface-600 dark:text-surface-400">{{ site.author.locality }}{% if site.author.country %}, <span class="p-country-name">{{ site.author.country }}</span>{% endif %}</p>
|
||||
{% if authorTitle %}
|
||||
<p class="p-job-title text-xs text-surface-600 dark:text-surface-400">{{ authorTitle }}</p>
|
||||
{% endif %}
|
||||
{% if authorLocality %}
|
||||
<p class="p-locality text-xs text-surface-600 dark:text-surface-400">{{ authorLocality }}{% if authorCountry %}, <span class="p-country-name">{{ authorCountry }}</span>{% endif %}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{# Hidden but present for microformat completeness #}
|
||||
<p class="p-note hidden">{{ site.author.bio }}</p>
|
||||
{% if site.author.email %}<data class="u-email hidden" value="{{ site.author.email }}"></data>{% endif %}
|
||||
{% if site.author.org %}<data class="p-org hidden" value="{{ site.author.org }}"></data>{% endif %}
|
||||
{% if authorBio %}<p class="p-note hidden">{{ authorBio }}</p>{% endif %}
|
||||
{% if authorEmail %}<data class="u-email hidden" value="{{ authorEmail }}"></data>{% endif %}
|
||||
{% if authorOrg %}<data class="p-org hidden" value="{{ authorOrg }}"></data>{% endif %}
|
||||
</div>
|
||||
</is-land>
|
||||
|
||||
@@ -2,14 +2,17 @@
|
||||
{# Requires fediverse-interact.js loaded in base.njk (already present) #}
|
||||
{# Determines actor URI from site social links: prefers self-hosted AP, falls back to Mastodon #}
|
||||
|
||||
{% set id = homepageConfig.identity if (homepageConfig and homepageConfig.identity) else {} %}
|
||||
{% set socialLinks = id.social if (id.social is defined) else site.social %}
|
||||
|
||||
{% set actorUrl = "" %}
|
||||
{% for link in site.social %}
|
||||
{% for link in socialLinks %}
|
||||
{% if link.icon == "activitypub" and not actorUrl %}
|
||||
{% set actorUrl = link.url %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% if not actorUrl %}
|
||||
{% for link in site.social %}
|
||||
{% for link in socialLinks %}
|
||||
{% if link.icon == "mastodon" and not actorUrl %}
|
||||
{% set actorUrl = link.url %}
|
||||
{% endif %}
|
||||
|
||||
@@ -4,7 +4,18 @@
|
||||
{% set ghFallbackFeatured = githubActivity.featured if githubActivity and githubActivity.featured else [] %}
|
||||
{% set ghFallbackContributions = githubActivity.contributions if githubActivity and githubActivity.contributions else [] %}
|
||||
{% set ghFallbackRepos = githubRepos if githubRepos else [] %}
|
||||
<div class="widget" x-data="githubWidget('{{ site.feeds.github }}')" x-init="init()">
|
||||
{% set id = homepageConfig.identity if (homepageConfig and homepageConfig.identity) else {} %}
|
||||
{% set socialLinks = id.social if (id.social is defined) else site.social %}
|
||||
{% set githubProfileUrl = "" %}
|
||||
{% for link in socialLinks %}
|
||||
{% if not githubProfileUrl and (link.icon == "github" or "github.com/" in link.url) %}
|
||||
{% set githubProfileUrl = link.url %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% if not githubProfileUrl and site.feeds.github %}
|
||||
{% set githubProfileUrl = "https://github.com/" + site.feeds.github %}
|
||||
{% endif %}
|
||||
<div class="widget" x-data="githubWidget('{{ site.feeds.github }}', '{{ githubProfileUrl }}')" x-init="init()">
|
||||
<h3 class="widget-title flex items-center gap-2">
|
||||
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path fill-rule="evenodd" d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" clip-rule="evenodd"></path>
|
||||
@@ -163,8 +174,8 @@
|
||||
</div>
|
||||
|
||||
{# Footer link #}
|
||||
{% if site.feeds.github %}
|
||||
<a href="https://github.com/{{ site.feeds.github }}" target="_blank" rel="noopener" class="text-sm text-accent-600 dark:text-accent-400 hover:underline mt-3 inline-flex items-center gap-1">
|
||||
{% if githubProfileUrl %}
|
||||
<a href="{{ githubProfileUrl }}" target="_blank" rel="noopener" class="text-sm text-accent-600 dark:text-accent-400 hover:underline mt-3 inline-flex items-center gap-1">
|
||||
View on GitHub
|
||||
<svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"/></svg>
|
||||
</a>
|
||||
@@ -179,7 +190,7 @@ const githubFallbackData = {
|
||||
repos: {{ ghFallbackRepos | dump | safe }},
|
||||
};
|
||||
|
||||
function githubWidget(username) {
|
||||
function githubWidget(username, profileUrl) {
|
||||
return {
|
||||
activeTab: 'commits',
|
||||
loading: true,
|
||||
@@ -199,6 +210,12 @@ function githubWidget(username) {
|
||||
return firstRepo.includes('/') ? firstRepo.split('/')[0] : '';
|
||||
},
|
||||
|
||||
deriveUsernameFromProfile(url) {
|
||||
if (!url || typeof url !== 'string') return '';
|
||||
const match = url.match(/github\.com\/([^/?#]+)/i);
|
||||
return match ? match[1] : '';
|
||||
},
|
||||
|
||||
async fetchJson(paths) {
|
||||
for (const path of paths) {
|
||||
try {
|
||||
@@ -270,7 +287,10 @@ function githubWidget(username) {
|
||||
this.contributions = contribRes.data?.contributions || [];
|
||||
}
|
||||
|
||||
let resolvedUsername = username;
|
||||
let resolvedUsername = this.deriveUsernameFromProfile(profileUrl);
|
||||
if (!resolvedUsername) {
|
||||
resolvedUsername = username;
|
||||
}
|
||||
if (!resolvedUsername) {
|
||||
resolvedUsername = this.deriveUsernameFromCommits(this.commits);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,25 @@
|
||||
{# Social Feed Widget - Tabbed Bluesky/Mastodon #}
|
||||
{% if (blueskyFeed and blueskyFeed.length) or (mastodonFeed and mastodonFeed.length) %}
|
||||
{% set id = homepageConfig.identity if (homepageConfig and homepageConfig.identity) else {} %}
|
||||
{% set socialLinks = id.social if (id.social is defined) else site.social %}
|
||||
|
||||
{% set blueskyProfileUrl = "" %}
|
||||
{% set mastodonProfileUrl = "" %}
|
||||
{% for link in socialLinks %}
|
||||
{% if not blueskyProfileUrl and (link.icon == "bluesky" or "bsky.app/profile/" in link.url) %}
|
||||
{% set blueskyProfileUrl = link.url %}
|
||||
{% endif %}
|
||||
{% if not mastodonProfileUrl and (link.icon == "mastodon" or "@" in link.url) %}
|
||||
{% set mastodonProfileUrl = link.url %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% if not blueskyProfileUrl and site.feeds.bluesky %}
|
||||
{% set blueskyProfileUrl = "https://bsky.app/profile/" + site.feeds.bluesky %}
|
||||
{% endif %}
|
||||
{% if not mastodonProfileUrl and site.feeds.mastodon.instance and site.feeds.mastodon.username %}
|
||||
{% set mastodonProfileUrl = "https://" + site.feeds.mastodon.instance + "/@" + site.feeds.mastodon.username %}
|
||||
{% endif %}
|
||||
|
||||
<is-land on:visible>
|
||||
{% set defaultSocialTab = "mastodon" if mastodonFeed and mastodonFeed.length else "bluesky" %}
|
||||
<div class="widget" x-data="{ activeTab: '{{ defaultSocialTab }}' }">
|
||||
@@ -60,10 +80,12 @@
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<a href="https://bsky.app/profile/{{ site.feeds.bluesky }}" target="_blank" rel="noopener" class="text-sm text-[#0085ff] hover:underline mt-3 inline-flex items-center gap-1">
|
||||
{% if blueskyProfileUrl %}
|
||||
<a href="{{ blueskyProfileUrl }}" target="_blank" rel="noopener" class="text-sm text-[#0085ff] hover:underline mt-3 inline-flex items-center gap-1">
|
||||
View on Bluesky
|
||||
<svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"/></svg>
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
@@ -90,10 +112,12 @@
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<a href="https://{{ site.feeds.mastodon.instance }}/@{{ site.feeds.mastodon.username }}" target="_blank" rel="noopener" class="text-sm text-[#a730b8] hover:underline mt-3 inline-flex items-center gap-1">
|
||||
{% if mastodonProfileUrl %}
|
||||
<a href="{{ mastodonProfileUrl }}" target="_blank" rel="noopener" class="text-sm text-[#a730b8] hover:underline mt-3 inline-flex items-center gap-1">
|
||||
View on Mastodon
|
||||
<svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"/></svg>
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
@@ -5,20 +5,20 @@
|
||||
Include in sidebar widgets, author cards, etc.
|
||||
#}
|
||||
{% set id = homepageConfig.identity if (homepageConfig and homepageConfig.identity) else {} %}
|
||||
{% set authorName = id.name or site.author.name %}
|
||||
{% set authorAvatar = id.avatar or site.author.avatar %}
|
||||
{% set authorTitle = id.title or site.author.title %}
|
||||
{% set authorBio = id.bio or site.author.bio %}
|
||||
{% set authorUrl = id.url or site.author.url %}
|
||||
{% set authorPronoun = id.pronoun or site.author.pronoun %}
|
||||
{% set authorLocality = id.locality or site.author.locality %}
|
||||
{% set authorCountry = id.country or site.author.country %}
|
||||
{% set authorLocation = site.author.location %}
|
||||
{% set authorOrg = id.org or site.author.org %}
|
||||
{% set authorEmail = id.email or site.author.email %}
|
||||
{% set authorKeyUrl = id.keyUrl or site.author.keyUrl %}
|
||||
{% set authorCategories = id.categories if (id.categories and id.categories.length) else site.author.categories %}
|
||||
{% set socialLinks = id.social if (id.social and id.social.length) else site.social %}
|
||||
{% set authorName = id.name if (id.name is defined) else site.author.name %}
|
||||
{% set authorAvatar = id.avatar if (id.avatar is defined) else site.author.avatar %}
|
||||
{% set authorTitle = id.title if (id.title is defined) else site.author.title %}
|
||||
{% set authorBio = id.bio if (id.bio is defined) else site.author.bio %}
|
||||
{% set authorUrl = id.url if (id.url is defined and id.url) else site.author.url %}
|
||||
{% set authorPronoun = id.pronoun if (id.pronoun is defined) else site.author.pronoun %}
|
||||
{% set authorLocality = id.locality if (id.locality is defined) else site.author.locality %}
|
||||
{% set authorCountry = id.country if (id.country is defined) else site.author.country %}
|
||||
{% set authorLocation = id.location if (id.location is defined) else site.author.location %}
|
||||
{% set authorOrg = id.org if (id.org is defined) else site.author.org %}
|
||||
{% set authorEmail = id.email if (id.email is defined) else site.author.email %}
|
||||
{% set authorKeyUrl = id.keyUrl if (id.keyUrl is defined) else site.author.keyUrl %}
|
||||
{% set authorCategories = id.categories if (id.categories is defined) else site.author.categories %}
|
||||
{% set socialLinks = id.social if (id.social is defined) else site.social %}
|
||||
|
||||
<div class="h-card p-author" itemscope itemtype="http://schema.org/Person">
|
||||
{# Hidden u-photo for reliable microformat parsing (some parsers struggle with img inside links) #}
|
||||
@@ -41,7 +41,9 @@
|
||||
{% if authorPronoun %}
|
||||
<span class="p-pronoun text-xs text-surface-500">({{ authorPronoun }})</span>
|
||||
{% endif %}
|
||||
{% if authorTitle %}
|
||||
<p class="p-job-title text-sm text-surface-600 dark:text-surface-400" itemprop="jobTitle">{{ authorTitle }}</p>
|
||||
{% endif %}
|
||||
{# Structured address #}
|
||||
<p class="p-adr h-adr text-sm text-surface-500 dark:text-surface-500" itemprop="address" itemscope itemtype="http://schema.org/PostalAddress">
|
||||
{% if authorLocality %}
|
||||
@@ -59,7 +61,9 @@
|
||||
</div>
|
||||
|
||||
{# Bio #}
|
||||
{% if authorBio %}
|
||||
<p class="p-note mt-3 text-sm text-surface-700 dark:text-surface-300" itemprop="description">{{ authorBio }}</p>
|
||||
{% endif %}
|
||||
|
||||
{# Organization #}
|
||||
{% if authorOrg %}
|
||||
|
||||
@@ -1,30 +1,43 @@
|
||||
{# Author Compact Card - h-card microformat (compact version for blog sidebars) #}
|
||||
{% set id = homepageConfig.identity if (homepageConfig and homepageConfig.identity) else {} %}
|
||||
{% set authorName = id.name if (id.name is defined) else site.author.name %}
|
||||
{% set authorAvatar = id.avatar if (id.avatar is defined) else site.author.avatar %}
|
||||
{% set authorTitle = id.title if (id.title is defined) else site.author.title %}
|
||||
{% set authorUrl = id.url if (id.url is defined and id.url) else site.author.url %}
|
||||
{% set authorLocality = id.locality if (id.locality is defined) else site.author.locality %}
|
||||
{% set authorCountry = id.country if (id.country is defined) else site.author.country %}
|
||||
{% set authorBio = id.bio if (id.bio is defined) else site.author.bio %}
|
||||
{% set authorEmail = id.email if (id.email is defined) else site.author.email %}
|
||||
{% set authorOrg = id.org if (id.org is defined) else site.author.org %}
|
||||
|
||||
<is-land on:visible>
|
||||
<div class="widget">
|
||||
<div class="h-card p-author flex items-center gap-3">
|
||||
{# Hidden u-photo for reliable microformat parsing #}
|
||||
<data class="u-photo hidden" value="{{ site.author.avatar }}"></data>
|
||||
<a href="{{ site.author.url }}" class="u-url u-uid" rel="me" itemprop="url">
|
||||
<data class="u-photo hidden" value="{{ authorAvatar }}"></data>
|
||||
<a href="{{ authorUrl }}" class="u-url u-uid" rel="me" itemprop="url">
|
||||
<img
|
||||
src="{{ site.author.avatar }}"
|
||||
alt="{{ site.author.name }}"
|
||||
src="{{ authorAvatar }}"
|
||||
alt="{{ authorName }}"
|
||||
class="w-12 h-12 rounded-full object-cover"
|
||||
loading="lazy"
|
||||
>
|
||||
</a>
|
||||
<div>
|
||||
<a href="{{ site.author.url }}" class="u-url p-name font-medium text-surface-900 dark:text-surface-100 hover:text-accent-600 dark:hover:text-accent-400">
|
||||
{{ site.author.name }}
|
||||
<a href="{{ authorUrl }}" class="u-url p-name font-medium text-surface-900 dark:text-surface-100 hover:text-accent-600 dark:hover:text-accent-400">
|
||||
{{ authorName }}
|
||||
</a>
|
||||
<p class="p-job-title text-xs text-surface-500">{{ site.author.title }}</p>
|
||||
{% if site.author.locality %}
|
||||
<p class="p-locality text-xs text-surface-500">{{ site.author.locality }}{% if site.author.country %}, <span class="p-country-name">{{ site.author.country }}</span>{% endif %}</p>
|
||||
{% if authorTitle %}
|
||||
<p class="p-job-title text-xs text-surface-500">{{ authorTitle }}</p>
|
||||
{% endif %}
|
||||
{% if authorLocality %}
|
||||
<p class="p-locality text-xs text-surface-500">{{ authorLocality }}{% if authorCountry %}, <span class="p-country-name">{{ authorCountry }}</span>{% endif %}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{# Hidden but present for microformat completeness #}
|
||||
<p class="p-note hidden">{{ site.author.bio }}</p>
|
||||
{% if site.author.email %}<data class="u-email hidden" value="{{ site.author.email }}"></data>{% endif %}
|
||||
{% if site.author.org %}<data class="p-org hidden" value="{{ site.author.org }}"></data>{% endif %}
|
||||
{% if authorBio %}<p class="p-note hidden">{{ authorBio }}</p>{% endif %}
|
||||
{% if authorEmail %}<data class="u-email hidden" value="{{ authorEmail }}"></data>{% endif %}
|
||||
{% if authorOrg %}<data class="p-org hidden" value="{{ authorOrg }}"></data>{% endif %}
|
||||
</div>
|
||||
</is-land>
|
||||
|
||||
@@ -2,14 +2,17 @@
|
||||
{# Requires fediverse-interact.js loaded in base.njk (already present) #}
|
||||
{# Determines actor URI from site social links: prefers self-hosted AP, falls back to Mastodon #}
|
||||
|
||||
{% set id = homepageConfig.identity if (homepageConfig and homepageConfig.identity) else {} %}
|
||||
{% set socialLinks = id.social if (id.social is defined) else site.social %}
|
||||
|
||||
{% set actorUrl = "" %}
|
||||
{% for link in site.social %}
|
||||
{% for link in socialLinks %}
|
||||
{% if link.icon == "activitypub" and not actorUrl %}
|
||||
{% set actorUrl = link.url %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% if not actorUrl %}
|
||||
{% for link in site.social %}
|
||||
{% for link in socialLinks %}
|
||||
{% if link.icon == "mastodon" and not actorUrl %}
|
||||
{% set actorUrl = link.url %}
|
||||
{% endif %}
|
||||
|
||||
@@ -4,7 +4,18 @@
|
||||
{% set ghFallbackFeatured = githubActivity.featured if githubActivity and githubActivity.featured else [] %}
|
||||
{% set ghFallbackContributions = githubActivity.contributions if githubActivity and githubActivity.contributions else [] %}
|
||||
{% set ghFallbackRepos = githubRepos if githubRepos else [] %}
|
||||
<div class="widget" x-data="githubWidget('{{ site.feeds.github }}')" x-init="init()">
|
||||
{% set id = homepageConfig.identity if (homepageConfig and homepageConfig.identity) else {} %}
|
||||
{% set socialLinks = id.social if (id.social is defined) else site.social %}
|
||||
{% set githubProfileUrl = "" %}
|
||||
{% for link in socialLinks %}
|
||||
{% if not githubProfileUrl and (link.icon == "github" or "github.com/" in link.url) %}
|
||||
{% set githubProfileUrl = link.url %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% if not githubProfileUrl and site.feeds.github %}
|
||||
{% set githubProfileUrl = "https://github.com/" + site.feeds.github %}
|
||||
{% endif %}
|
||||
<div class="widget" x-data="githubWidget('{{ site.feeds.github }}', '{{ githubProfileUrl }}')" x-init="init()">
|
||||
<h3 class="widget-title flex items-center gap-2">
|
||||
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path fill-rule="evenodd" d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" clip-rule="evenodd"></path>
|
||||
@@ -155,8 +166,8 @@
|
||||
</div>
|
||||
|
||||
{# Footer link #}
|
||||
{% if site.feeds.github %}
|
||||
<a href="https://github.com/{{ site.feeds.github }}" target="_blank" rel="noopener" class="text-sm text-accent-600 dark:text-accent-400 hover:underline mt-3 inline-flex items-center gap-1">
|
||||
{% if githubProfileUrl %}
|
||||
<a href="{{ githubProfileUrl }}" target="_blank" rel="noopener" class="text-sm text-accent-600 dark:text-accent-400 hover:underline mt-3 inline-flex items-center gap-1">
|
||||
View on GitHub
|
||||
<svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"/></svg>
|
||||
</a>
|
||||
@@ -171,7 +182,7 @@ const githubFallbackData = {
|
||||
repos: {{ ghFallbackRepos | dump | safe }},
|
||||
};
|
||||
|
||||
function githubWidget(username) {
|
||||
function githubWidget(username, profileUrl) {
|
||||
return {
|
||||
activeTab: 'commits',
|
||||
loading: true,
|
||||
@@ -191,6 +202,12 @@ function githubWidget(username) {
|
||||
return firstRepo.includes('/') ? firstRepo.split('/')[0] : '';
|
||||
},
|
||||
|
||||
deriveUsernameFromProfile(url) {
|
||||
if (!url || typeof url !== 'string') return '';
|
||||
const match = url.match(/github\.com\/([^/?#]+)/i);
|
||||
return match ? match[1] : '';
|
||||
},
|
||||
|
||||
async fetchJson(paths) {
|
||||
for (const path of paths) {
|
||||
try {
|
||||
@@ -262,7 +279,10 @@ function githubWidget(username) {
|
||||
this.contributions = contribRes.data?.contributions || [];
|
||||
}
|
||||
|
||||
let resolvedUsername = username;
|
||||
let resolvedUsername = this.deriveUsernameFromProfile(profileUrl);
|
||||
if (!resolvedUsername) {
|
||||
resolvedUsername = username;
|
||||
}
|
||||
if (!resolvedUsername) {
|
||||
resolvedUsername = this.deriveUsernameFromCommits(this.commits);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,25 @@
|
||||
{# Social Feed Widget - Tabbed Bluesky/Mastodon #}
|
||||
{% if (blueskyFeed and blueskyFeed.length) or (mastodonFeed and mastodonFeed.length) %}
|
||||
{% set id = homepageConfig.identity if (homepageConfig and homepageConfig.identity) else {} %}
|
||||
{% set socialLinks = id.social if (id.social is defined) else site.social %}
|
||||
|
||||
{% set blueskyProfileUrl = "" %}
|
||||
{% set mastodonProfileUrl = "" %}
|
||||
{% for link in socialLinks %}
|
||||
{% if not blueskyProfileUrl and (link.icon == "bluesky" or "bsky.app/profile/" in link.url) %}
|
||||
{% set blueskyProfileUrl = link.url %}
|
||||
{% endif %}
|
||||
{% if not mastodonProfileUrl and (link.icon == "mastodon" or "@" in link.url) %}
|
||||
{% set mastodonProfileUrl = link.url %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% if not blueskyProfileUrl and site.feeds.bluesky %}
|
||||
{% set blueskyProfileUrl = "https://bsky.app/profile/" + site.feeds.bluesky %}
|
||||
{% endif %}
|
||||
{% if not mastodonProfileUrl and site.feeds.mastodon.instance and site.feeds.mastodon.username %}
|
||||
{% set mastodonProfileUrl = "https://" + site.feeds.mastodon.instance + "/@" + site.feeds.mastodon.username %}
|
||||
{% endif %}
|
||||
|
||||
<is-land on:visible>
|
||||
{% set defaultSocialTab = "mastodon" if mastodonFeed and mastodonFeed.length else "bluesky" %}
|
||||
<div class="widget" x-data="{ activeTab: '{{ defaultSocialTab }}' }">
|
||||
@@ -56,10 +76,12 @@
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<a href="https://bsky.app/profile/{{ site.feeds.bluesky }}" target="_blank" rel="noopener" class="text-sm text-[#0085ff] hover:underline mt-3 inline-flex items-center gap-1">
|
||||
{% if blueskyProfileUrl %}
|
||||
<a href="{{ blueskyProfileUrl }}" target="_blank" rel="noopener" class="text-sm text-[#0085ff] hover:underline mt-3 inline-flex items-center gap-1">
|
||||
View on Bluesky
|
||||
<svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"/></svg>
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
@@ -86,10 +108,12 @@
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<a href="https://{{ site.feeds.mastodon.instance }}/@{{ site.feeds.mastodon.username }}" target="_blank" rel="noopener" class="text-sm text-[#a730b8] hover:underline mt-3 inline-flex items-center gap-1">
|
||||
{% if mastodonProfileUrl %}
|
||||
<a href="{{ mastodonProfileUrl }}" target="_blank" rel="noopener" class="text-sm text-[#a730b8] hover:underline mt-3 inline-flex items-center gap-1">
|
||||
View on Mastodon
|
||||
<svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"/></svg>
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user