diff --git a/.gitmodules b/.gitmodules
index 085e293..23565b8 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -7,3 +7,10 @@
 [submodule "roles.extern/epel-simplified"]
 	path = roles.extern/epel-simplified
 	url = https://git.velt.biz/Ansible/epel-simplified
+[submodule "roles.extern/dokuwiki_inventory"]
+	path = roles.extern/dokuwiki_inventory
+	url = https://git.velt.biz/Ansible/dokuwiki_inventory.git
+[submodule "roles.extern/dokuwiki_inventory.devel"]
+	path = roles.extern/dokuwiki_inventory.devel
+	url = https://git.velt.biz/Ansible/dokuwiki_inventory.git
+	branch = devel
diff --git a/07/dokuwiki_inventory.devel.yml b/07/dokuwiki_inventory.devel.yml
new file mode 100644
index 0000000..40b8ba4
--- /dev/null
+++ b/07/dokuwiki_inventory.devel.yml
@@ -0,0 +1,7 @@
+---
+- hosts: all
+
+  roles:
+    - role: dokuwiki_inventory.devel
+      doku_path: /tmp/dokuwiki_inventory.devel
+
diff --git a/07/dokuwiki_inventory.yml b/07/dokuwiki_inventory.yml
new file mode 120000
index 0000000..2cfd15e
--- /dev/null
+++ b/07/dokuwiki_inventory.yml
@@ -0,0 +1 @@
+../roles.extern/dokuwiki_inventory/dokuwiki_inventory.yml
\ No newline at end of file
diff --git a/07/install_dokuwiki.yml b/07/install_dokuwiki.yml
new file mode 100644
index 0000000..1e7df0f
--- /dev/null
+++ b/07/install_dokuwiki.yml
@@ -0,0 +1,61 @@
+---
+- hosts: all
+
+  tasks:
+    - debug:
+       var: ansible_os_family
+
+    - name: Sanity check
+      assert:
+        that:
+          - ansible_os_family == "Debian"
+#          - ansible_distribution_major_version == "12"
+
+    - name: Install packages
+      package:
+        name:
+          - apache2
+          - php-fpm
+          - dokuwiki
+      notify: Restart Apache2
+
+    - name: Fix Dokuwiki config for Apache
+      lineinfile:
+        dest: /etc/apache2/conf-available/dokuwiki.conf
+        regex: "	Allow from localhost"
+        line: "	Allow from all"
+        backup: yes
+      notify: Restart Apache2
+
+    - name: Enable Apache configurations
+      file:
+        state: link
+        src: "../conf-available/{{ item }}"
+        dest: "/etc/apache2/conf-enabled/{{ item }}"
+      loop:
+        - dokuwiki.conf
+        - php8.2-fpm.conf
+      notify: Restart Apache2
+
+    - name: Enable Apache2 modules
+      apache2_module:
+        name: "{{ item }}"
+        state: present
+      loop:
+        - proxy
+        - proxy_fcgi
+      notify: Restart Apache2
+
+  handlers:
+    - name: Stop Apache2
+      service:
+        name: apache2
+        state: stopped
+      listen: Restart Apache2
+
+    - name: Start Apache2
+      service:
+        name: apache2
+        state: started
+      listen: Restart Apache2
+
diff --git a/07/jinja2_filter.yml b/07/jinja2_filter.yml
new file mode 100644
index 0000000..39bd91b
--- /dev/null
+++ b/07/jinja2_filter.yml
@@ -0,0 +1,75 @@
+---
+- hosts: localhost
+  gather_facts: no
+
+  vars:
+    # var_undefined
+    var_zahl: 23
+    var_string: "Hallo Teilnehmer!"
+    var_liste_leer: []
+    var_liste: [Hund, Katze, Maus]
+    var_liste_mapping:
+      - firstname: Sven
+      - firstname: Berta
+      - firstname: Klara
+      - firstname: "X Æ A-12"
+      - firstname: Axel
+    var_bool_true: True
+    var_bool_false: False
+
+  tasks:
+    - name: 'default-Filter'
+      debug:
+        msg:
+          - "var_undefined|default(42)        → {{ var_undefined|default(42) }}"
+          - "var_zahl|default(42)             → {{ var_zahl|default(42) }}"
+          - "var_liste_leer|default(42)       → {{ var_liste_leer|default(42) }}"
+          - "var_liste_leer|default(42, true) → {{ var_liste_leer|default(42, true) }}"
+
+    - name: 'String-Filter'
+      debug:
+        msg:
+          - "var_string|lower      → {{ var_string|lower }}"
+          - "var_string|upper      → {{ var_string|upper }}"
+          - "var_string|capitalize → {{ var_string|capitalize }}"
+
+    - name: 'ternary-Filter'
+      debug:
+        msg:
+          - "var_bool_true|ternary('Ja','Nein')  → {{ var_bool_true|ternary('Ja','Nein') }}"
+          - "var_bool_false|ternary('Ja','Nein') → {{ var_bool_false|ternary('Ja','Nein') }}"
+          - "var_string|ternary('Ja','Nein')     → {{ var_string|ternary('Ja','Nein') }}"
+
+    - name: 'list-Filter'
+      debug:
+        msg:
+          - "var_liste|join(', ')                                     → {{ var_liste|join(', ') }}"
+          - "var_liste_mapping|join(' sowie ', attribute='firstname') → {{ var_liste_mapping|join(' sowie ', attribute='firstname') }}"
+
+    - name: 'Datei-Filter'
+      debug:
+        msg:
+          - "'/usr/local/bin/ansible'|basename → {{ '/usr/local/bin/ansible'|basename }}"
+          - "'/usr/local/bin/ansible'|dirname  → {{ '/usr/local/bin/ansible'|dirname }}"
+          - "'/usr/local/bin'|dirname          → {{ '/usr/local/bin'|dirname }}"
+          - "'/usr/local/bin/.'|dirname        → {{ '/usr/local/bin/.'|dirname }}"
+
+    - name: 'ipaddr-Filter'
+      debug:
+        msg:
+          - "'192.168.128.42/28'|ansible.utils.ipaddr                   → {{ '192.168.128.42/28'|ansible.utils.ipaddr }}"
+          - "'192.168.128.42/28'|ansible.utils.ipv4                     → {{ '192.168.128.42/28'|ansible.utils.ipv4 }}"
+          - "'192.168.128.42/28'|ansible.utils.ipv6                     → {{ '192.168.128.42/28'|ansible.utils.ipv6 }}"
+          - "'192.168.128.42/28'|ansible.utils.ipaddr('address')        → {{ '192.168.128.42/28'|ansible.utils.ipaddr('address') }}"
+          - "'192.168.128.42/28'|ansible.utils.ipaddr('network')        → {{ '192.168.128.42/28'|ansible.utils.ipaddr('network') }}"
+          - "'192.168.128.42/28'|ansible.utils.ipaddr('size')           → {{ '192.168.128.42/28'|ansible.utils.ipaddr('size') }}"
+          - "'192.168.128.42/28'|ansible.utils.ipaddr('broadcast')      → {{ '192.168.128.42/28'|ansible.utils.ipaddr('broadcast') }}"
+          - "'192.168.128.42/28'|ansible.utils.ipaddr('network/prefix') → {{ '192.168.128.42/28'|ansible.utils.ipaddr('network/prefix') }}"
+
+    - name: 'ipaddr-Filter für eine Range'
+      debug:
+        msg:
+          - "'192.168.128.42/28'|ansible.utils.ipaddr('network/prefix')|ansible.utils.ipaddr(2) → {{ '192.168.128.42/28'|ansible.utils.ipaddr('network/prefix')|ansible.utils.ipaddr(2) }}"
+          - "'192.168.128.42/28'|ansible.utils.ipaddr('network/prefix')|ansible.utils.nthhost(-3) → {{ '192.168.128.42/28'|ansible.utils.ipaddr('network/prefix')|ansible.utils.nthhost(-3) }}"
+          - "'192.168.128.42/28'|ansible.utils.ipaddr('last_usable') → {{ '192.168.128.42/28'|ansible.utils.ipaddr('last_usable') }}"
+
diff --git a/07/jinja2_for-if.j2 b/07/jinja2_for-if.j2
new file mode 100644
index 0000000..97d3524
--- /dev/null
+++ b/07/jinja2_for-if.j2
@@ -0,0 +1,10 @@
+{% for u in users if not u.hidden %}
+  {{ loop.cycle('+', '-', ' ') }} {{ loop.index }} {{ loop.first }}
+  {% if u.sex == "M" %}Herr
+  {% elif u.sex == "W" %}Frau
+  {% else %}Divers
+  {% endif %} {{ u.firstname }} {{ u.lastname }}
+{% else %}
+  Keine Benutzer gefunden!
+{% endfor %}
+
diff --git a/07/jinja2_for-if.txt b/07/jinja2_for-if.txt
new file mode 100644
index 0000000..fcbcc2f
--- /dev/null
+++ b/07/jinja2_for-if.txt
@@ -0,0 +1,13 @@
+  + 1 True
+  Herr
+   Sven Velt
+  - 2 False
+  Frau
+   Klara Verstand
+    3 False
+  Divers
+   X Æ A-12 Musk
+  + 4 False
+  Herr
+   Axel Schweiss
+
diff --git a/07/jinja2_for-if.yml b/07/jinja2_for-if.yml
new file mode 100644
index 0000000..d3b59d3
--- /dev/null
+++ b/07/jinja2_for-if.yml
@@ -0,0 +1,12 @@
+---
+- hosts: localhost
+  gather_facts: no
+
+  vars_files:
+    - var_users.yml
+
+  tasks:
+    - template:
+        src: jinja2_for-if.j2
+        dest: jinja2_for-if.txt
+
diff --git a/07/jinja2_localhost_interface-list.j2 b/07/jinja2_localhost_interface-list.j2
new file mode 100644
index 0000000..9e93deb
--- /dev/null
+++ b/07/jinja2_localhost_interface-list.j2
@@ -0,0 +1,4 @@
+{% for intname in ansible_interfaces %}
+- {{ intname }}: {{ ansible_facts[ intname|replace('-', '_')]['macaddress']|default('-') }}
+{% endfor %}
+
diff --git a/07/jinja2_localhost_interface-list.txt b/07/jinja2_localhost_interface-list.txt
new file mode 100644
index 0000000..3e3ebef
--- /dev/null
+++ b/07/jinja2_localhost_interface-list.txt
@@ -0,0 +1,39 @@
+- veth9tuUab: fe:c6:6e:2d:37:47
+- vethsbqt3E: fe:97:65:4a:ea:79
+- vethDzmsZE: fe:4c:88:c8:e6:21
+- vethz83qdd: fe:2e:fc:55:6b:da
+- veth4okp9f: fe:0b:17:14:b1:d0
+- vethCOuH4a: fe:85:b6:2b:e1:bf
+- lxcbr0: 00:16:3e:00:00:00
+- eth0: bc:24:11:d3:01:19
+- vethutzBeV: fe:0e:73:59:ff:8c
+- vethpc5mmF: fe:7f:8d:dc:21:59
+- veth3dky0y: fe:2a:04:64:d0:70
+- vethqIuvN4: fe:8f:84:04:08:e0
+- vethTPr6rD: fe:46:e7:c1:29:e2
+- vethss4VTW: fe:dc:cd:ef:c5:17
+- vethkxTpmB: fe:7c:71:4c:23:38
+- lo: -
+- vethXVA3b7: fe:03:04:6e:b0:f2
+- vethexbn7g: fe:67:69:30:5b:d5
+- vethyu4LoK: fe:e3:47:09:b4:0a
+- vethSIGrkv: fe:19:cd:85:a7:f7
+- vethopVhm9: fe:54:ec:c3:da:24
+- vethEVMS3F: fe:8f:5a:ed:01:5e
+- vethNknT2n: fe:47:ca:c1:9e:0d
+- vethRCfqNI: fe:fe:ce:bc:57:bd
+- vethDr0ikH: fe:cf:96:1d:31:8f
+- vethkoPbDc: fe:6a:44:b3:18:8f
+- vethKvXX6G: fe:b9:05:19:d2:f2
+- vethrg1dS8: fe:3d:ce:d2:2c:ef
+- vethwUPIeM: fe:dd:6f:44:d1:ff
+- vethDTpz2e: fe:47:c9:a8:f6:61
+- vethIiYpve: fe:fc:02:fe:b4:23
+- vethb9oDV7: fe:de:56:39:f0:9b
+- vethpLQaLU: fe:d3:9f:ad:14:15
+- vethSzJZ59: fe:c6:03:8c:d8:a5
+- vethemM109: fe:2e:75:d9:8e:dc
+- vethng0Zki: fe:9d:53:8a:53:e8
+- vethyZCApU: fe:ab:61:ff:85:c9
+- vethPfX7c9: fe:32:b8:84:d3:a5
+
diff --git a/07/jinja2_localhost_interface-list.yml b/07/jinja2_localhost_interface-list.yml
new file mode 100644
index 0000000..b622c9b
--- /dev/null
+++ b/07/jinja2_localhost_interface-list.yml
@@ -0,0 +1,9 @@
+---
+- hosts: localhost
+
+  tasks:
+    - template:
+        src: jinja2_localhost_interface-list.j2
+        dest: jinja2_localhost_interface-list.txt
+
+
diff --git a/07/jinja2_variablen_verwenden.yml b/07/jinja2_variablen_verwenden.yml
new file mode 100644
index 0000000..14e2839
--- /dev/null
+++ b/07/jinja2_variablen_verwenden.yml
@@ -0,0 +1,32 @@
+---
+- hosts: localhost
+  gather_facts: no
+  vars_files:
+    - var_user.yml
+
+  vars:
+    field: firstname
+
+  tasks:
+    - name: 'user'
+      debug:
+        msg: '{{ user }}'
+
+    - name: 'user["firstname"] '
+      debug:
+        msg: '{{ user["firstname"] }}'
+
+    - name: 'user.firstname '
+      debug:
+        msg: '{{ user.firstname }}'
+
+    - name: 'user[field]'
+      debug:
+        msg: '{{ user[field] }}'
+
+    - name: 'user[field] mit Task-Var'
+      debug:
+        msg: '{{ user[field] }}'
+      vars:
+        field: lastname
+
diff --git a/07/uebung_1.j2 b/07/uebung_1.j2
new file mode 100644
index 0000000..ba574af
--- /dev/null
+++ b/07/uebung_1.j2
@@ -0,0 +1,12 @@
+# Meine NTP-Server:
+
+## Als Liste
+{{ chrony_pools }}
+
+## Als String mit join-Filter
+{{ chrony_pools|join(", ") }}
+
+## In einer for-Schleife
+{% for n in chrony_pools %}{{ loop.index }}: {{ n }}
+{% endfor %}
+
diff --git a/07/uebung_1.yml b/07/uebung_1.yml
new file mode 100644
index 0000000..34130a6
--- /dev/null
+++ b/07/uebung_1.yml
@@ -0,0 +1,9 @@
+---
+- hosts: all
+
+  tasks:
+    - local_action:
+        module: template
+        src: uebung_1.j2
+        dest: "/tmp/uebung_1_{{ inventory_hostname}}.txt"
+
diff --git a/07/uebung_2.j2 b/07/uebung_2.j2
new file mode 100644
index 0000000..a8ce1cb
--- /dev/null
+++ b/07/uebung_2.j2
@@ -0,0 +1,12 @@
+# Netzwerk-Daten
+IP: {{ ansible_default_ipv4.address }}
+Netzmaske: {{ ansible_default_ipv4.netmask }}
+Gateway: {{ ansible_default_ipv4.gateway }}
+
+# IPv6
+## Als String
+{{ ansible_all_ipv6_addresses|join(" und ") }}
+## Als Schleife
+{% for a in ansible_all_ipv6_addresses %}{{ loop.index }}{{ loop.cycle('-', ' ', ' ')}}{{ a }}
+{% endfor %}
+
diff --git a/07/uebung_2.yml b/07/uebung_2.yml
new file mode 100644
index 0000000..f560502
--- /dev/null
+++ b/07/uebung_2.yml
@@ -0,0 +1,8 @@
+---
+- hosts: localhost
+
+  tasks:
+    - template:
+        src: uebung_2.j2
+        dest: "/tmp/uebung_2_{{ inventory_hostname}}.txt"
+
diff --git a/07/var_user.yml b/07/var_user.yml
new file mode 100644
index 0000000..3bca41d
--- /dev/null
+++ b/07/var_user.yml
@@ -0,0 +1,8 @@
+---
+user:
+  firstname: Sven
+  lastname: Velt
+  sex: M
+  year: 1975
+  hidden: no
+
diff --git a/07/var_users.yml b/07/var_users.yml
new file mode 100644
index 0000000..77f13f1
--- /dev/null
+++ b/07/var_users.yml
@@ -0,0 +1,28 @@
+---
+users:
+  - firstname: Sven
+    lastname: Velt
+    sex: M
+    year: 1975
+    hidden: no
+  - firstname: Berta
+    lastname: Müller
+    sex: W
+    year: 1923
+    hidden: yes
+  - firstname: Klara
+    lastname: Verstand
+    sex: W
+    year: 1989
+    hidden: no
+  - firstname: "X Æ A-12"
+    lastname: Musk
+    sex: unbekannt
+    year: 2020
+    hidden: no
+  - firstname: Axel
+    lastname: Schweiss
+    sex: M
+    year: 1999
+    hidden: no
+
diff --git a/helper/07_gitmodules.sh b/helper/07_gitmodules.sh
new file mode 100755
index 0000000..490fead
--- /dev/null
+++ b/helper/07_gitmodules.sh
@@ -0,0 +1,7 @@
+#!/bin/bash -ex
+
+mkdir -p roles.extern
+
+git submodule add https://git.velt.biz/Ansible/dokuwiki_inventory.git roles.extern/dokuwiki_inventory
+git submodule add -b devel https://git.velt.biz/Ansible/dokuwiki_inventory.git roles.extern/dokuwiki_inventory.devel
+
diff --git a/helper/07_packages.sh b/helper/07_packages.sh
new file mode 100755
index 0000000..5714247
--- /dev/null
+++ b/helper/07_packages.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+sudo apt install --no-install-recommends --yes python3-netaddr
+
diff --git a/hosts.localhost b/hosts.localhost
new file mode 100644
index 0000000..978b00c
--- /dev/null
+++ b/hosts.localhost
@@ -0,0 +1 @@
+localhost	ansible_connection=local
diff --git a/roles.extern/dokuwiki_inventory b/roles.extern/dokuwiki_inventory
new file mode 160000
index 0000000..25d3363
--- /dev/null
+++ b/roles.extern/dokuwiki_inventory
@@ -0,0 +1 @@
+Subproject commit 25d3363a39612f342e44d1f1de90e5df7b4c9b50
diff --git a/roles.extern/dokuwiki_inventory.devel b/roles.extern/dokuwiki_inventory.devel
new file mode 160000
index 0000000..0ef7eb8
--- /dev/null
+++ b/roles.extern/dokuwiki_inventory.devel
@@ -0,0 +1 @@
+Subproject commit 0ef7eb89052b3ccce9bdfaded8feb8da49b915ed