Solved link bug with subitems

This commit is contained in:
Kevin Veen-Birkenbach 2025-01-10 13:56:37 +01:00
parent dc058d16df
commit 28cd3e1f2f
3 changed files with 89 additions and 75 deletions

View File

@ -171,25 +171,7 @@ navigation:
url: mailto:kevin@veen.world
identifier: kevin@veen.world
alternatives:
- link: navigation.header.contact.matrix
- name: Matrix
description: Chat with me on Matrix
icon:
class: fa-solid fa-cubes
identifier: "@kevinveenbirkenbach:veen.world"
info: |
#### Why Use Matrix?
Matrix is a secure, decentralized communication platform that ensures privacy and control over your data. Learn more about [Matrix](https://matrix.org/).
#### Privacy and Security
End-to-end encryption keeps your conversations private and secure.
#### Decentralized and Open
Matrix's federated network means you can host your own server or use any provider while staying connected.
#### A Movement for Digital Freedom
By using Matrix, you support open, transparent, and secure communication.
- link: navigation.header.contact.messenger.matrix
- name: Mobile
description: Call me
icon:
@ -215,7 +197,28 @@ navigation:
#### Stand for Security
Using PGP is more than a tool—it's a statement about valuing freedom, privacy, and the security of digital communication. Explore the principles of secure communication with [privacy guides](https://privacyguides.org/).
- name: Messenger
description: Social and developer networks
icon:
class: fa-brands fa-meta
subitems:
- name: Matrix
description: Chat with me on Matrix
icon:
class: fa-solid fa-cubes
identifier: "@kevinveenbirkenbach:veen.world"
info: |
#### Why Use Matrix?
Matrix is a secure, decentralized communication platform that ensures privacy and control over your data. Learn more about [Matrix](https://matrix.org/).
#### Privacy and Security
End-to-end encryption keeps your conversations private and secure.
#### Decentralized and Open
Matrix's federated network means you can host your own server or use any provider while staying connected.
#### A Movement for Digital Freedom
By using Matrix, you support open, transparent, and secure communication.
- name: Signal
description: Message me on Signal
icon:
@ -223,7 +226,7 @@ navigation:
identifier: "+491781798023"
warning: Signal is not hosted by me!
alternatives:
- link: navigation.header.contact.matrix
- link: navigation.header.contact.messenger.matrix
- name: Telegram
description: Message me on Telegram
icon:
@ -233,7 +236,7 @@ navigation:
identifier: kevinveenbirkenbach
warning: Telegram is not hosted by me!
alternatives:
- link: navigation.header.contact.matrix
- link: navigation.header.contact.messenger.matrix
- name: WhatsApp
description: Chat with me on WhatsApp
icon:
@ -243,12 +246,12 @@ navigation:
warning: Using software and platforms from the Meta corporation (e.g., Facebook, Instagram, WhatsApp) may compromise your data privacy and digital freedom due to centralized control, extensive data collection practices, and inconsistent moderation policies. These platforms often fail to adequately address harmful content, misinformation, and abuse.
info: Consider using decentralized and privacy-respecting alternatives to maintain control over your data, improve security, and foster healthier online interactions.
alternatives:
- link: navigation.header.contact.matrix
- link: navigation.header.contact.signal
- link: navigation.header.contact.telegram
- link: navigation.header.contact.messenger.matrix
- link: navigation.header.contact.messenger.signal
- link: navigation.header.contact.messenger.telegram
footer:
- name: External Accounts
- name: Accounts
description: Me on other plattforms
icon:
class: fa-solid fa-external-link-alt
@ -269,14 +272,7 @@ navigation:
icon:
class: fa-brands fa-facebook
url: https://www.facebook.com/kevinveenbirkenbach
- name: Communication
description: Social and developer networks
icon:
class: fa-brands fa-meta
subitems:
- link: navigation.header.contact.whatsapp
- link: navigation.header.contact.signal
- link: navigation.header.contact.telegram
- link: navigation.header.contact.messenger
- name: Carreer Profiles
icon:
class: fa-solid fa-user-tie

View File

@ -4,7 +4,11 @@
{% if subitem.subitems %}
<li class="dropdown-submenu position-relative">
<a class="dropdown-item dropdown-toggle" href="#" title="{{ subitem.description }}">
{% if subitem.icon is defined and subitem.icon.class is defined %}
<i class="{{ subitem.icon.class }}"></i> {{ subitem.name }}
{% else %}
<p>Missing icon in subitem: {{ subitem }}</p>
{% endif %}
</a>
<ul class="dropdown-menu">
{{ render_subitems(subitem.subitems) }}

View File

@ -1,3 +1,4 @@
from pprint import pprint
class ConfigurationResolver:
"""
A class to resolve `link` entries in a nested configuration structure.
@ -21,7 +22,10 @@ class ConfigurationResolver:
for key, value in list(current_config.items()):
if key == "link":
try:
target = self._find_entry(root_config, value.lower())
target = self._find_entry(root_config, value.lower(), True)
if isinstance(target, list) and len(target) > 2:
target = self._find_entry(root_config, value.lower(), False)
current_config.clear()
current_config.update(target)
except Exception as e:
@ -35,7 +39,18 @@ class ConfigurationResolver:
for item in current_config:
self._recursive_resolve(item, root_config)
def _find_entry(self, config, path):
def _get_subitems(self,current):
if isinstance(current, dict) and ("subitems" in current and current["subitems"]):
current = current["subitems"]
return current
def _find_by_name(self,current, part):
return next(
(item for item in current if isinstance(item, dict) and item.get("name", "").lower() == part),
None
)
def _find_entry(self, config, path, subitems):
"""
Finds an entry in the configuration by a dot-separated path.
Supports both dictionaries and lists with `subitems` navigation.
@ -45,10 +60,7 @@ class ConfigurationResolver:
for part in parts:
if isinstance(current, list):
# Look for a matching name in the list
found = next(
(item for item in current if isinstance(item, dict) and item.get("name", "").lower() == part),
None
)
found = self._find_by_name(current,part)
if found:
print(
f"Matching entry for '{part}' in list. Path so far: {' > '.join(parts[:parts.index(part)+1])}. "
@ -64,20 +76,22 @@ class ConfigurationResolver:
# Case-insensitive dictionary lookup
key = next((k for k in current if k.lower() == part), None)
if key is None:
current = self._find_by_name(current["subitems"],part)
if not current:
raise KeyError(
f"Key '{part}' not found in dictionary. Path so far: {' > '.join(parts[:parts.index(part)+1])}. "
f"Current dictionary: {current}"
)
else:
current = current[key]
else:
raise ValueError(
f"Invalid path segment '{part}'. Current type: {type(current)}. "
f"Path so far: {' > '.join(parts[:parts.index(part)+1])}"
)
# Navigate into `subitems` if present
if isinstance(current, dict) and ("subitems" in current and current["subitems"]):
current = current["subitems"]
if subitems:
current = self._get_subitems(current)
return current