mirror of
				https://github.com/kevinveenbirkenbach/homepage.veen.world.git
				synced 2025-11-04 09:27:58 +00:00 
			
		
		
		
	Refactored code and implemented new childrens loading
This commit is contained in:
		@@ -4,12 +4,12 @@ accounts:
 | 
				
			|||||||
  description: My Online Accounts
 | 
					  description: My Online Accounts
 | 
				
			||||||
  icon:
 | 
					  icon:
 | 
				
			||||||
      class: fa-solid fa-users
 | 
					      class: fa-solid fa-users
 | 
				
			||||||
  subitems:
 | 
					  children:
 | 
				
			||||||
  - name: Publications
 | 
					  - name: Publications
 | 
				
			||||||
    description: My Publications
 | 
					    description: My Publications
 | 
				
			||||||
    icon:
 | 
					    icon:
 | 
				
			||||||
        class: fas fa-newspaper
 | 
					        class: fas fa-newspaper
 | 
				
			||||||
    subitems:
 | 
					    children:
 | 
				
			||||||
    - name: Microblog
 | 
					    - name: Microblog
 | 
				
			||||||
      description: Read my microblogs
 | 
					      description: Read my microblogs
 | 
				
			||||||
      icon:
 | 
					      icon:
 | 
				
			||||||
@@ -19,7 +19,7 @@ accounts:
 | 
				
			|||||||
    - name: Pictures
 | 
					    - name: Pictures
 | 
				
			||||||
      icon:
 | 
					      icon:
 | 
				
			||||||
        class: fa-solid fa-images
 | 
					        class: fa-solid fa-images
 | 
				
			||||||
      subitems:
 | 
					      children:
 | 
				
			||||||
      - name: Pixelfed  
 | 
					      - name: Pixelfed  
 | 
				
			||||||
        description: View my photo gallery
 | 
					        description: View my photo gallery
 | 
				
			||||||
        icon:
 | 
					        icon:
 | 
				
			||||||
@@ -49,7 +49,7 @@ accounts:
 | 
				
			|||||||
      icon:
 | 
					      icon:
 | 
				
			||||||
          class: fa-solid fa-laptop-code
 | 
					          class: fa-solid fa-laptop-code
 | 
				
			||||||
      description: Check out my Code
 | 
					      description: Check out my Code
 | 
				
			||||||
      subitems:
 | 
					      children:
 | 
				
			||||||
      - name: Github
 | 
					      - name: Github
 | 
				
			||||||
        description: View my GitHub profile
 | 
					        description: View my GitHub profile
 | 
				
			||||||
        icon:
 | 
					        icon:
 | 
				
			||||||
@@ -66,7 +66,7 @@ accounts:
 | 
				
			|||||||
    icon:
 | 
					    icon:
 | 
				
			||||||
      class: fa-brands fa-meta
 | 
					      class: fa-brands fa-meta
 | 
				
			||||||
    url: 
 | 
					    url: 
 | 
				
			||||||
    subitems:
 | 
					    children:
 | 
				
			||||||
    - name: Facebook
 | 
					    - name: Facebook
 | 
				
			||||||
      description: Like my Facebook page
 | 
					      description: Like my Facebook page
 | 
				
			||||||
      icon:
 | 
					      icon:
 | 
				
			||||||
@@ -76,7 +76,7 @@ accounts:
 | 
				
			|||||||
  - name: Carreer Profiles
 | 
					  - name: Carreer Profiles
 | 
				
			||||||
    icon:
 | 
					    icon:
 | 
				
			||||||
      class: fa-solid fa-user-tie
 | 
					      class: fa-solid fa-user-tie
 | 
				
			||||||
    subitems:
 | 
					    children:
 | 
				
			||||||
    - name: XING
 | 
					    - name: XING
 | 
				
			||||||
      description: Visit my XING profile
 | 
					      description: Visit my XING profile
 | 
				
			||||||
      icon:
 | 
					      icon:
 | 
				
			||||||
@@ -94,7 +94,7 @@ accounts:
 | 
				
			|||||||
    icon:
 | 
					    icon:
 | 
				
			||||||
      class: fa-solid fa-running
 | 
					      class: fa-solid fa-running
 | 
				
			||||||
    url: 
 | 
					    url: 
 | 
				
			||||||
    subitems:
 | 
					    children:
 | 
				
			||||||
    - name: Garmin
 | 
					    - name: Garmin
 | 
				
			||||||
      description: My Garmin activities
 | 
					      description: My Garmin activities
 | 
				
			||||||
      icon:
 | 
					      icon:
 | 
				
			||||||
@@ -251,16 +251,18 @@ company:
 | 
				
			|||||||
  imprint_url: https://s.veen.world/imprint
 | 
					  imprint_url: https://s.veen.world/imprint
 | 
				
			||||||
navigation:
 | 
					navigation:
 | 
				
			||||||
  header:
 | 
					  header:
 | 
				
			||||||
 | 
					    children:
 | 
				
			||||||
 | 
					    - link: accounts.publications.children
 | 
				
			||||||
    - name: Contact
 | 
					    - name: Contact
 | 
				
			||||||
      description: Get in touch
 | 
					      description: Get in touch
 | 
				
			||||||
      icon:
 | 
					      icon:
 | 
				
			||||||
          class: fa-solid fa-envelope
 | 
					          class: fa-solid fa-envelope
 | 
				
			||||||
    subitems:
 | 
					      children:
 | 
				
			||||||
      - name: Email
 | 
					      - name: Email
 | 
				
			||||||
        description: Send me an email
 | 
					        description: Send me an email
 | 
				
			||||||
        icon:
 | 
					        icon:
 | 
				
			||||||
          class: fa-solid fa-envelope
 | 
					          class: fa-solid fa-envelope
 | 
				
			||||||
      subitems:
 | 
					        children:
 | 
				
			||||||
        - name: Email
 | 
					        - name: Email
 | 
				
			||||||
          description: Send me an email
 | 
					          description: Send me an email
 | 
				
			||||||
          icon:
 | 
					          icon:
 | 
				
			||||||
@@ -298,7 +300,7 @@ navigation:
 | 
				
			|||||||
        description: Social and developer networks
 | 
					        description: Social and developer networks
 | 
				
			||||||
        icon:
 | 
					        icon:
 | 
				
			||||||
          class: fa-solid fa-comments
 | 
					          class: fa-solid fa-comments
 | 
				
			||||||
      subitems: 
 | 
					        children: 
 | 
				
			||||||
        - name: Matrix
 | 
					        - name: Matrix
 | 
				
			||||||
          description: Chat with me on Matrix
 | 
					          description: Chat with me on Matrix
 | 
				
			||||||
          icon:
 | 
					          icon:
 | 
				
			||||||
@@ -345,20 +347,20 @@ navigation:
 | 
				
			|||||||
            - link: navigation.header.contact.messenger.matrix
 | 
					            - link: navigation.header.contact.messenger.matrix
 | 
				
			||||||
            - link: navigation.header.contact.messenger.signal
 | 
					            - link: navigation.header.contact.messenger.signal
 | 
				
			||||||
            - link: navigation.header.contact.messenger.telegram
 | 
					            - link: navigation.header.contact.messenger.telegram
 | 
				
			||||||
 | 
					 | 
				
			||||||
  footer:
 | 
					  footer:
 | 
				
			||||||
 | 
					    children:
 | 
				
			||||||
    - link: accounts
 | 
					    - link: accounts
 | 
				
			||||||
    - name: Solution Hub
 | 
					    - name: Solution Hub
 | 
				
			||||||
      description: Curated collection of self hosted tools
 | 
					      description: Curated collection of self hosted tools
 | 
				
			||||||
      icon:
 | 
					      icon:
 | 
				
			||||||
          class: fa-solid fa-network-wired
 | 
					          class: fa-solid fa-network-wired
 | 
				
			||||||
      url: 
 | 
					      url: 
 | 
				
			||||||
    subitems:
 | 
					      children:
 | 
				
			||||||
      - name: Community
 | 
					      - name: Community
 | 
				
			||||||
        description: Tools to manage the community
 | 
					        description: Tools to manage the community
 | 
				
			||||||
        icon:
 | 
					        icon:
 | 
				
			||||||
            class: fa-solid fa-users
 | 
					            class: fa-solid fa-users
 | 
				
			||||||
      subitems:
 | 
					        children:
 | 
				
			||||||
        - name: Forum
 | 
					        - name: Forum
 | 
				
			||||||
          description: Join the discussion
 | 
					          description: Join the discussion
 | 
				
			||||||
          icon:
 | 
					          icon:
 | 
				
			||||||
@@ -378,7 +380,7 @@ navigation:
 | 
				
			|||||||
        description: Project Management Tools
 | 
					        description: Project Management Tools
 | 
				
			||||||
        icon:
 | 
					        icon:
 | 
				
			||||||
            class: fa-solid fa-chart-line
 | 
					            class: fa-solid fa-chart-line
 | 
				
			||||||
      subitems:
 | 
					        children:
 | 
				
			||||||
        - name: Open Project
 | 
					        - name: Open Project
 | 
				
			||||||
          description: Explore my projects
 | 
					          description: Explore my projects
 | 
				
			||||||
          icon:
 | 
					          icon:
 | 
				
			||||||
@@ -394,7 +396,7 @@ navigation:
 | 
				
			|||||||
      - name: Communication
 | 
					      - name: Communication
 | 
				
			||||||
        icon:
 | 
					        icon:
 | 
				
			||||||
          class: fa-solid fa-comments
 | 
					          class: fa-solid fa-comments
 | 
				
			||||||
      subitems:
 | 
					        children:
 | 
				
			||||||
        - name: Elements
 | 
					        - name: Elements
 | 
				
			||||||
          description: Chat with me
 | 
					          description: Chat with me
 | 
				
			||||||
          icon:
 | 
					          icon:
 | 
				
			||||||
@@ -415,7 +417,7 @@ navigation:
 | 
				
			|||||||
      - name: Tools
 | 
					      - name: Tools
 | 
				
			||||||
        icon:
 | 
					        icon:
 | 
				
			||||||
          class: fas fa-tools
 | 
					          class: fas fa-tools
 | 
				
			||||||
      subitems:
 | 
					        children:
 | 
				
			||||||
        - name: Matomo
 | 
					        - name: Matomo
 | 
				
			||||||
          description: Analyze with Matomo
 | 
					          description: Analyze with Matomo
 | 
				
			||||||
          icon:
 | 
					          icon:
 | 
				
			||||||
@@ -443,12 +445,12 @@ navigation:
 | 
				
			|||||||
      description: All information about me
 | 
					      description: All information about me
 | 
				
			||||||
      icon:
 | 
					      icon:
 | 
				
			||||||
          class: fa-solid fa-user
 | 
					          class: fa-solid fa-user
 | 
				
			||||||
    subitems:
 | 
					      children:
 | 
				
			||||||
      - name: Logbooks
 | 
					      - name: Logbooks
 | 
				
			||||||
        description: Access my personal logbooks (diving, flying, sailing)
 | 
					        description: Access my personal logbooks (diving, flying, sailing)
 | 
				
			||||||
        icon:
 | 
					        icon:
 | 
				
			||||||
            class: fa-solid fa-book
 | 
					            class: fa-solid fa-book
 | 
				
			||||||
      subitems:
 | 
					        children:
 | 
				
			||||||
        - name: Skydiver
 | 
					        - name: Skydiver
 | 
				
			||||||
          description: View my skydiving logs
 | 
					          description: View my skydiving logs
 | 
				
			||||||
          icon:
 | 
					          icon:
 | 
				
			||||||
@@ -483,11 +485,12 @@ navigation:
 | 
				
			|||||||
        icon:
 | 
					        icon:
 | 
				
			||||||
            class: fa-solid fa-file-lines
 | 
					            class: fa-solid fa-file-lines
 | 
				
			||||||
        url: https://s.veen.world/lebenslauf
 | 
					        url: https://s.veen.world/lebenslauf
 | 
				
			||||||
 | 
					      - link: accounts
 | 
				
			||||||
      - name: Credentials
 | 
					      - name: Credentials
 | 
				
			||||||
        description: Access my certifications, degrees, and professional records
 | 
					        description: Access my certifications, degrees, and professional records
 | 
				
			||||||
        icon:
 | 
					        icon:
 | 
				
			||||||
          class: fa-solid fa-id-card
 | 
					          class: fa-solid fa-id-card
 | 
				
			||||||
      subitems:
 | 
					        children:
 | 
				
			||||||
          - name: Degrees
 | 
					          - name: Degrees
 | 
				
			||||||
            description: View my academic degrees
 | 
					            description: View my academic degrees
 | 
				
			||||||
            icon:
 | 
					            icon:
 | 
				
			||||||
@@ -503,10 +506,10 @@ navigation:
 | 
				
			|||||||
            icon:
 | 
					            icon:
 | 
				
			||||||
              class: fa-solid fa-scroll
 | 
					              class: fa-solid fa-scroll
 | 
				
			||||||
            url: https://s.veen.world/certifications
 | 
					            url: https://s.veen.world/certifications
 | 
				
			||||||
    - link: accounts
 | 
					 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
    - name: Imprint
 | 
					    - name: Imprint
 | 
				
			||||||
      description: Check out the imprint information
 | 
					      description: Check out the imprint information
 | 
				
			||||||
      icon:
 | 
					      icon:
 | 
				
			||||||
          class: fa-solid fa-scale-balanced
 | 
					          class: fa-solid fa-scale-balanced
 | 
				
			||||||
      url: https://s.veen.world/imprint
 | 
					      url: https://s.veen.world/imprint
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
@@ -1,33 +1,33 @@
 | 
				
			|||||||
<!-- Template for Subitems -->
 | 
					{% macro render_icon_and_name(item) %}
 | 
				
			||||||
{% macro render_subitems(subitems) %}
 | 
					    <i class="{{ item.icon.class if item.icon is defined and item.icon.class is defined else 'fa-solid fa-link' }}"></i>
 | 
				
			||||||
    {% for subitem in subitems %}
 | 
					    {% if item.name is defined %}
 | 
				
			||||||
        {% if subitem.subitems %}
 | 
					        {{ item.name }}
 | 
				
			||||||
            <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 %}
 | 
					    {% else %}
 | 
				
			||||||
                        <p>Missing icon in subitem: {{ subitem }}</p>
 | 
					        Unnamed Item: {{item}}
 | 
				
			||||||
    {% endif %}
 | 
					    {% endif %}
 | 
				
			||||||
 | 
					{% endmacro %}
 | 
				
			||||||
 | 
					<!-- Template for children -->
 | 
				
			||||||
 | 
					{% macro render_children(children) %}
 | 
				
			||||||
 | 
					    {% for children in children %}
 | 
				
			||||||
 | 
					        {% if children.children %}
 | 
				
			||||||
 | 
					            <li class="dropdown-submenu position-relative">
 | 
				
			||||||
 | 
					                <a class="dropdown-item dropdown-toggle" href="#" title="{{ children.description }}">
 | 
				
			||||||
 | 
					                    {{ render_icon_and_name(children) }}
 | 
				
			||||||
                </a>
 | 
					                </a>
 | 
				
			||||||
                <ul class="dropdown-menu">
 | 
					                <ul class="dropdown-menu">
 | 
				
			||||||
                    {{ render_subitems(subitem.subitems) }}
 | 
					                    {{ render_children(children.children) }}
 | 
				
			||||||
                </ul>
 | 
					                </ul>
 | 
				
			||||||
            </li>
 | 
					            </li>
 | 
				
			||||||
        {% elif subitem.identifier or subitem.warning or subitem.info %}
 | 
					        {% elif children.identifier or children.warning or children.info %}
 | 
				
			||||||
            <li>
 | 
					            <li>
 | 
				
			||||||
                <a class="dropdown-item" onclick='openDynamicPopup({{ subitem|tojson|safe }})' data-bs-toggle="tooltip" title="{{ subitem.description }}">
 | 
					                <a class="dropdown-item" onclick='openDynamicPopup({{ children|tojson|safe }})' data-bs-toggle="tooltip" title="{{ children.description }}">
 | 
				
			||||||
                    <i class="{{ subitem.icon.class }}"></i> {{ subitem.name }}
 | 
					                    {{ render_icon_and_name(children) }}
 | 
				
			||||||
                </a>
 | 
					                </a>
 | 
				
			||||||
            </li>
 | 
					            </li>
 | 
				
			||||||
        {% else %}
 | 
					        {% else %}
 | 
				
			||||||
            <li>
 | 
					            <li>
 | 
				
			||||||
                <a class="dropdown-item" href="{{ subitem.url }}" target="{{ subitem.target|default('_blank') }}" data-bs-toggle="tooltip" title="{{ subitem.description }}">
 | 
					                <a class="dropdown-item" href="{{ children.url }}" target="{{ children.target|default('_blank') }}" data-bs-toggle="tooltip" title="{{ children.description }}">
 | 
				
			||||||
                    {% if subitem.icon is defined and subitem.icon.class is defined %}
 | 
					                     {{ render_icon_and_name(children) }}
 | 
				
			||||||
                        <i class="{{ subitem.icon.class }}"></i> {{ subitem.name }}
 | 
					 | 
				
			||||||
                    {% else %}
 | 
					 | 
				
			||||||
                        <p>Missing icon in subitem: {{ subitem }}</p>
 | 
					 | 
				
			||||||
                    {% endif %}
 | 
					 | 
				
			||||||
                </a>
 | 
					                </a>
 | 
				
			||||||
            </li>
 | 
					            </li>
 | 
				
			||||||
        {% endif %}
 | 
					        {% endif %}
 | 
				
			||||||
@@ -42,12 +42,12 @@
 | 
				
			|||||||
        </button>
 | 
					        </button>
 | 
				
			||||||
        <div class="collapse navbar-collapse" id="navbarNav{{menu_type}}">
 | 
					        <div class="collapse navbar-collapse" id="navbarNav{{menu_type}}">
 | 
				
			||||||
            <ul class="navbar-nav {% if menu_type == 'header' %}ms-auto{% endif %}">
 | 
					            <ul class="navbar-nav {% if menu_type == 'header' %}ms-auto{% endif %}">
 | 
				
			||||||
                {% for item in navigation[menu_type] %}
 | 
					                {% for item in navigation[menu_type].children %}
 | 
				
			||||||
                    {% if item.url %}
 | 
					                    {% if item.url %}
 | 
				
			||||||
                        <!-- Single Item -->
 | 
					                        <!-- Single Item -->
 | 
				
			||||||
                        <li class="nav-item">
 | 
					                        <li class="nav-item">
 | 
				
			||||||
                            <a class="nav-link" href="{{ item.url }}" target="{{ item.target|default('_blank') }}" data-bs-toggle="tooltip" title="{{ item.description }}">
 | 
					                            <a class="nav-link" href="{{ item.url }}" target="{{ item.target|default('_blank') }}" data-bs-toggle="tooltip" title="{{ item.description }}">
 | 
				
			||||||
                                <i class="{{ item.icon.class }}"></i> {{ item.name }}
 | 
					                                {{ render_icon_and_name(item) }}
 | 
				
			||||||
                            </a>
 | 
					                            </a>
 | 
				
			||||||
                        </li>
 | 
					                        </li>
 | 
				
			||||||
                    {% else %}
 | 
					                    {% else %}
 | 
				
			||||||
@@ -55,13 +55,13 @@
 | 
				
			|||||||
                        <li class="nav-item dropdown">
 | 
					                        <li class="nav-item dropdown">
 | 
				
			||||||
                            <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown{{ loop.index }}" role="button" data-bs-toggle="dropdown" data-bs-display="dynamic" aria-expanded="false">
 | 
					                            <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown{{ loop.index }}" role="button" data-bs-toggle="dropdown" data-bs-display="dynamic" aria-expanded="false">
 | 
				
			||||||
                                {% if item.icon is defined and item.icon.class is defined %}
 | 
					                                {% if item.icon is defined and item.icon.class is defined %}
 | 
				
			||||||
                                    <i class="{{ item.icon.class }}"></i> {{ item.name }}
 | 
					                                    {{ render_icon_and_name(item) }}
 | 
				
			||||||
                                {% else %}
 | 
					                                {% else %}
 | 
				
			||||||
                                    <p>Missing icon in item: {{ item }}</p>
 | 
					                                    <p>Missing icon in item: {{ item }}</p>
 | 
				
			||||||
                                {% endif %}
 | 
					                                {% endif %}
 | 
				
			||||||
                            </a>
 | 
					                            </a>
 | 
				
			||||||
                            <ul class="dropdown-menu">
 | 
					                            <ul class="dropdown-menu">
 | 
				
			||||||
                                {{ render_subitems(item.subitems) }}
 | 
					                                {{ render_children(item.children) }}
 | 
				
			||||||
                            </ul>
 | 
					                            </ul>
 | 
				
			||||||
                        </li>
 | 
					                        </li>
 | 
				
			||||||
                    {% endif %}
 | 
					                    {% endif %}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@ from pprint import pprint
 | 
				
			|||||||
class ConfigurationResolver:
 | 
					class ConfigurationResolver:
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    A class to resolve `link` entries in a nested configuration structure.
 | 
					    A class to resolve `link` entries in a nested configuration structure.
 | 
				
			||||||
    Supports navigation through dictionaries, lists, and `subitems`.
 | 
					    Supports navigation through dictionaries, lists, and `children`.
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, config):
 | 
					    def __init__(self, config):
 | 
				
			||||||
@@ -14,23 +14,58 @@ class ConfigurationResolver:
 | 
				
			|||||||
        """
 | 
					        """
 | 
				
			||||||
        self._recursive_resolve(self.config, self.config)
 | 
					        self._recursive_resolve(self.config, self.config)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __load_children(self,path):
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        Check if explicitly children should be loaded and not parent
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        return path.split('.').pop() == "children"
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    def _replace_in_dict_by_dict(self, dict_origine, old_key, new_dict):
 | 
				
			||||||
 | 
					        if old_key in dict_origine:
 | 
				
			||||||
 | 
					            # Entferne den alten Key
 | 
				
			||||||
 | 
					            old_value = dict_origine.pop(old_key)
 | 
				
			||||||
 | 
					            # Füge die neuen Key-Value-Paare hinzu
 | 
				
			||||||
 | 
					            dict_origine.update(new_dict)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _replace_in_list_by_list(self, list_origine, old_element, new_elements):
 | 
				
			||||||
 | 
					        index = list_origine.index(old_element)
 | 
				
			||||||
 | 
					        list_origine[index:index+1] = new_elements
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _replace_element_in_list(self, list_origine, old_element, new_element):
 | 
				
			||||||
 | 
					        index = list_origine.index(old_element)
 | 
				
			||||||
 | 
					        list_origine[index] = new_element
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _recursive_resolve(self, current_config, root_config):
 | 
					    def _recursive_resolve(self, current_config, root_config):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Recursively resolves `link` entries in the configuration.
 | 
					        Recursively resolves `link` entries in the configuration.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        if isinstance(current_config, dict):
 | 
					        if isinstance(current_config, dict):
 | 
				
			||||||
            for key, value in list(current_config.items()):
 | 
					            for key, value in list(current_config.items()):
 | 
				
			||||||
                if key == "link":
 | 
					                if key == "children":
 | 
				
			||||||
 | 
					                    for item in value:
 | 
				
			||||||
 | 
					                        if "link" in item:
 | 
				
			||||||
 | 
					                            loaded_link = self._find_entry(root_config, item['link'].lower(), False)
 | 
				
			||||||
 | 
					                            if isinstance(loaded_link, list):
 | 
				
			||||||
 | 
					                                self._replace_in_list_by_list(value,item,loaded_link)
 | 
				
			||||||
 | 
					                            else:
 | 
				
			||||||
 | 
					                                self._replace_element_in_list(value,item,loaded_link)             
 | 
				
			||||||
 | 
					                elif key == "link":
 | 
				
			||||||
                    try:
 | 
					                    try:
 | 
				
			||||||
                        target = self._find_entry(root_config, value.lower(), True)
 | 
					                        if self.__load_children(value):
 | 
				
			||||||
                        if isinstance(target, list) and len(target) > 2:
 | 
					                            loaded = self._find_entry(root_config, value.lower(), False)
 | 
				
			||||||
                            target = self._find_entry(root_config, value.lower(), False)    
 | 
					                            self._replace_in_dict_by_dict(
 | 
				
			||||||
 | 
					                                    current_config,key,loaded
 | 
				
			||||||
 | 
					                                )
 | 
				
			||||||
 | 
					                        else:
 | 
				
			||||||
 | 
					                            loaded = self._find_entry(root_config, value.lower(), True)
 | 
				
			||||||
 | 
					                            if isinstance(loaded, list) and len(loaded) > 2:
 | 
				
			||||||
 | 
					                                loaded = self._find_entry(root_config, value.lower(), False)  
 | 
				
			||||||
                            current_config.clear()
 | 
					                            current_config.clear()
 | 
				
			||||||
                        current_config.update(target)
 | 
					                            current_config.update(loaded)
 | 
				
			||||||
                    except Exception as e: 
 | 
					                    except Exception as e: 
 | 
				
			||||||
                        raise ValueError(
 | 
					                        raise ValueError(
 | 
				
			||||||
                            f"Error resolving link '{value}': {str(e)}. "
 | 
					                            f"Error resolving link '{value}': {str(e)}. "
 | 
				
			||||||
                            f"Current path: {key}, Current config: {current_config}"
 | 
					                            f"Current path: {key}, Current config: {current_config}" + (f", Loaded: {loaded}" if 'loaded' in locals() or 'loaded' in globals() else "")
 | 
				
			||||||
                        )
 | 
					                        )
 | 
				
			||||||
                else:
 | 
					                else:
 | 
				
			||||||
                    self._recursive_resolve(value, root_config)
 | 
					                    self._recursive_resolve(value, root_config)
 | 
				
			||||||
@@ -38,9 +73,9 @@ class ConfigurationResolver:
 | 
				
			|||||||
            for item in current_config:
 | 
					            for item in current_config:
 | 
				
			||||||
                self._recursive_resolve(item, root_config)
 | 
					                self._recursive_resolve(item, root_config)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _get_subitems(self,current):
 | 
					    def _get_children(self,current):
 | 
				
			||||||
        if isinstance(current, dict) and ("subitems" in current and current["subitems"]):
 | 
					        if isinstance(current, dict) and ("children" in current and current["children"]):
 | 
				
			||||||
            current = current["subitems"]
 | 
					            current = current["children"]
 | 
				
			||||||
        return current
 | 
					        return current
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _find_by_name(self,current, part):
 | 
					    def _find_by_name(self,current, part):
 | 
				
			||||||
@@ -49,18 +84,21 @@ class ConfigurationResolver:
 | 
				
			|||||||
                    None
 | 
					                    None
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _find_entry(self, config, path, subitems):
 | 
					    def _find_entry(self, config, path, children):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Finds an entry in the configuration by a dot-separated path.
 | 
					        Finds an entry in the configuration by a dot-separated path.
 | 
				
			||||||
        Supports both dictionaries and lists with `subitems` navigation.
 | 
					        Supports both dictionaries and lists with `children` navigation.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        parts = path.split('.')
 | 
					        parts = path.split('.')
 | 
				
			||||||
        current = config
 | 
					        current = config
 | 
				
			||||||
        for part in parts:
 | 
					        for part in parts:
 | 
				
			||||||
            if isinstance(current, list):
 | 
					            if isinstance(current, list):
 | 
				
			||||||
 | 
					                # If children explicit declared just load children
 | 
				
			||||||
 | 
					                if part != "children":
 | 
				
			||||||
                    # Look for a matching name in the list
 | 
					                    # Look for a matching name in the list
 | 
				
			||||||
                    found = self._find_by_name(current,part)
 | 
					                    found = self._find_by_name(current,part)
 | 
				
			||||||
                    if found:
 | 
					                    if found:
 | 
				
			||||||
 | 
					                        current = found
 | 
				
			||||||
                        print(
 | 
					                        print(
 | 
				
			||||||
                            f"Matching entry for '{part}' in list. Path so far: {' > '.join(parts[:parts.index(part)+1])}. "
 | 
					                            f"Matching entry for '{part}' in list. Path so far: {' > '.join(parts[:parts.index(part)+1])}. "
 | 
				
			||||||
                            f"Current list: {current}"
 | 
					                            f"Current list: {current}"
 | 
				
			||||||
@@ -70,12 +108,11 @@ class ConfigurationResolver:
 | 
				
			|||||||
                            f"No matching entry for '{part}' in list. Path so far: {' > '.join(parts[:parts.index(part)+1])}. "
 | 
					                            f"No matching entry for '{part}' in list. Path so far: {' > '.join(parts[:parts.index(part)+1])}. "
 | 
				
			||||||
                            f"Current list: {current}"
 | 
					                            f"Current list: {current}"
 | 
				
			||||||
                        )
 | 
					                        )
 | 
				
			||||||
                current = found
 | 
					 | 
				
			||||||
            elif isinstance(current, dict):
 | 
					            elif isinstance(current, dict):
 | 
				
			||||||
                # Case-insensitive dictionary lookup
 | 
					                # Case-insensitive dictionary lookup
 | 
				
			||||||
                key = next((k for k in current if k.lower() == part), None)
 | 
					                key = next((k for k in current if k.lower() == part), None)
 | 
				
			||||||
                if key is None:
 | 
					                if key is None:
 | 
				
			||||||
                    current = self._find_by_name(current["subitems"],part)
 | 
					                    current = self._find_by_name(current["children"],part)
 | 
				
			||||||
                    if not current:
 | 
					                    if not current:
 | 
				
			||||||
                        raise KeyError(
 | 
					                        raise KeyError(
 | 
				
			||||||
                            f"Key '{part}' not found in dictionary. Path so far: {' > '.join(parts[:parts.index(part)+1])}. "
 | 
					                            f"Key '{part}' not found in dictionary. Path so far: {' > '.join(parts[:parts.index(part)+1])}. "
 | 
				
			||||||
@@ -89,8 +126,8 @@ class ConfigurationResolver:
 | 
				
			|||||||
                    f"Invalid path segment '{part}'. Current type: {type(current)}. "
 | 
					                    f"Invalid path segment '{part}'. Current type: {type(current)}. "
 | 
				
			||||||
                    f"Path so far: {' > '.join(parts[:parts.index(part)+1])}"
 | 
					                    f"Path so far: {' > '.join(parts[:parts.index(part)+1])}"
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
            if subitems:
 | 
					            if children:
 | 
				
			||||||
                current = self._get_subitems(current)
 | 
					                current = self._get_children(current)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return current
 | 
					        return current
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user