Merge branch 'main' into feature/slides

This commit is contained in:
Prof. Dr. Matthias Jung DL9MJ
2025-06-24 22:07:23 +02:00
committed by Tim Grelka
11 changed files with 422 additions and 27 deletions
+5 -4
View File
@@ -4,8 +4,9 @@ import requests
class DirectusAPI:
def __init__(self, config):
self.config = config
def __init__(self, base_url, access_token):
self.base_url = base_url
self.access_token = access_token
def __get_raw(self, endpoint, params = None):
if params is None:
@@ -13,12 +14,12 @@ class DirectusAPI:
for k in params.keys():
if type(params[k]) is dict:
params[k] = json.dumps(params[k])
url = self.config.base_url + endpoint
url = self.base_url + endpoint
result = requests.get(
url,
params = params,
headers = {
"Authorization": f"Bearer {self.config.access_token}",
"Authorization": f"Bearer {self.access_token}",
"Cache-Control": "no-store"
}
)
+7 -5
View File
@@ -4,8 +4,9 @@ import src.config as config
import src.download as download
conf = config.Config()
api = directus.DirectusAPI(conf)
dl = download.Download(api, conf)
api = directus.DirectusAPI(conf.question_base_url, conf.question_access_token)
content_api = directus.DirectusAPI(conf.content_base_url, conf.content_access_token)
dl = download.Download(api, content_api, conf)
bd = build.Build()
# Download the text files:
@@ -15,9 +16,10 @@ dl.download_edition("N")
dl.download_question_metadata()
dl.download_pictures()
dl.download_photos()
dl.download_snippets()
dl.download_content()
# Build edition:
# Build Everything:
bd.build_website()
bd.build_edition("N")
# Build assets:
bd.build_assets()
+4 -1
View File
@@ -1,4 +1,7 @@
{
"directus_base_url" : "https://fragenkatalog.darc.de/",
"directus_question_base_url" : "https://fragenkatalog.darc.de/",
"directus_question_api_key" : "",
"directus_content_base_url" : "https://redaktion.50ohm.de/",
"directus_content_api_key" : "",
"no_latex": true
}
+89 -10
View File
@@ -3,7 +3,6 @@ import os
import random
import shutil
from bs4 import BeautifulSoup
from jinja2 import Environment, FileSystemLoader
from joblib import Memory
from mistletoe import Document
@@ -98,9 +97,13 @@ class Build:
return self.__build_question(input, template_file="slide/question.html")
# cached
def __build_page(self, content) :
def __build_page(self, content, course_wrapper=False, sidebar=None) :
page_template = self.env.get_template("html/page.html")
return page_template.render(content=content)
return page_template.render(
content=content,
course_wrapper=course_wrapper,
sidebar=sidebar
)
def __picture_handler(self, id):
os.makedirs("build/pictures", exist_ok=True)
@@ -132,8 +135,7 @@ class Build:
title=next_chapter["title"],
)
result = self.__build_page(result)
result = BeautifulSoup(result, "html.parser").prettify()
result = self.__build_page(result, course_wrapper=True)
file.write(result)
# cached
@@ -169,8 +171,34 @@ class Build:
title=next_chapter["title"],
)
result = self.__build_page(result)
result = BeautifulSoup(result, "html.parser").prettify()
result = self.__build_page(result, course_wrapper=True)
file.write(result)
def __build_chapter_slidedeck(self, edition, chapter, sections, next_chapter):
with open(f'build/{edition}_slide_{chapter["ident"]}.html', 'w') as file:
slide_template = self.env.get_template("slide/slide.html")
help_template = self.env.get_template("slide/help.html")
next_template = self.env.get_template("slide/next.html")
with FiftyOhmHtmlSlideRenderer(
question_renderer=self.__build_question_slide,
picture_handler=self.__picture_handler,
photo_handler=self.__photo_handler
) as renderer:
result = "<section>\n"
result += f'<section data-background="#DAEEFA">\n<h1>{chapter["title"]}</h1>\n</section>\n'
result += help_template.render()
result += "</section>\n"
for section in sections:
tmp = f'<section data-background="#DAEEFA">\n<h1>{section["title"]}</h1>\n</section>\n'
tmp += renderer.render_wrapper(section["slide"])
result += f"<section>{tmp}</section>\n"
result += next_template.render(
edition=edition,
next_chapter=next_chapter,
chapter=chapter,
)
result = slide_template.render(content=result)
file.write(result)
def __build_chapter_slidedeck(self, edition, chapter, sections, next_chapter):
@@ -219,7 +247,6 @@ class Build:
book=book,
)
result = self.__build_page(result)
result = BeautifulSoup(result, "html.parser").prettify()
file.write(result)
def __build_slide_index(self, book):
@@ -229,7 +256,6 @@ class Build:
book=book,
)
result = self.__build_page(result)
result = BeautifulSoup(result, "html.parser").prettify()
file.write(result)
def build_edition(self, edition):
@@ -251,4 +277,57 @@ class Build:
self.__build_section(edition, edition_name, section, i, chapter, next_section, next_chapter)
def build_assets(self):
shutil.copytree("assets", "build/assets", dirs_exist_ok=True)
shutil.copytree("assets", "build/assets", dirs_exist_ok=True)
def __parse_snippets(self):
with open("data/snippets.json") as f:
snippets = json.load(f)
with FiftyOhmHtmlRenderer(self.__build_question, self.__picture_handler, self.__photo_handler) as renderer:
for key, value in snippets.items():
snippets[key] = renderer.render_inner(Document(value))
# Remove leading <p> and trailing </p>:
snippets[key] = snippets[key][3:-4]
return snippets
def __parse_contents(self):
with open("data/content.json") as f:
contents = json.load(f)
return contents
def __build_index(self, snippets):
template = self.env.get_template("index.html")
result = template.render({"snippets": snippets})
with open("build/index.html", "w") as file:
result = self.__build_page(result)
file.write(result)
def __build_course_page(self, snippets, template, page):
template = self.env.get_template(f"{template}.html")
result=template.render({"snippets": snippets})
with open(f"build/{page}.html", "w") as file:
result = self.__build_page(result)
file.write(result)
def __build_html_page(self, contents, page):
for content in contents:
if content["url_part"] == page:
with open(f"build/{page}.html", "w") as file:
result = self.__build_page(
content=content["content"],
sidebar=content["sidebar"]
)
file.write(result)
def build_website(self):
snippets = self.__parse_snippets()
contents = self.__parse_contents()
self.__build_index(snippets)
self.__build_course_page(snippets, "kurse-karte", "kurse_vor_ort_karte")
self.__build_course_page(snippets, "kurse-liste", "kurse_vor_ort_liste")
self.__build_course_page(snippets, "patenkarte", "patenkarte")
self.__build_html_page(contents, "pruefung")
self.__build_html_page(contents, "infos")
+4 -2
View File
@@ -13,8 +13,10 @@ class Config:
with open("config/config.json") as file:
self.config = json.load(file)
self.access_token = self.get_config_value("directus_api_key")
self.base_url = self.get_config_value("directus_api_url", "https://fragenkatalog.darc.de/")
self.question_access_token = self.get_config_value("directus_question_api_key")
self.question_base_url = self.get_config_value("directus_question_base_url", "https://fragenkatalog.darc.de/")
self.content_access_token = self.get_config_value("directus_content_api_key")
self.content_base_url = self.get_config_value("directus_content_base_url", "https://redaktion.50ohm.de/")
self.no_latex = self.get_config_value("no_latex", False)
def get_config_value(self, key: str, default=None):
+23 -1
View File
@@ -8,9 +8,10 @@ from tqdm import tqdm
class Download:
def __init__(self, api, config):
def __init__(self, api, content_api, config):
self.api = api
self.config = config
self.content_api = content_api
def download_edition(self, edition):
in_edition = self.api.get_one("items/edition", {"filter": {"ident": {"_eq": edition}}})
@@ -131,3 +132,24 @@ class Download:
Parallel(n_jobs=multiprocessing.cpu_count())(
delayed(build_picture)(picture) for picture in tqdm(pictures, desc="Build All Pictures")
)
def download_snippets(self):
snippets = {}
for snippet in tqdm(self.content_api.get("items/snippet"), desc="Downloading snippets"):
snippets[snippet["ident"]] = snippet["content"]
with open("data/snippets.json", "w", encoding="utf-8") as file:
json.dump(snippets, file, ensure_ascii=False, indent=4)
def download_content(self):
contents = []
for content in self.content_api.get("items/content"): #tqdm(self.content_api.get("items/content"), desc="Downloading content"):
contents.append(
{
"url_part": content["url_part"],
"content": content["content"],
"sidebar": content["sidebar"],
}
)
with open("data/content.json", "w", encoding="utf-8") as file:
json.dump(contents, file, ensure_ascii=False, indent=4)
+184
View File
@@ -0,0 +1,184 @@
<div class="fiftyohm-content-index">
<div>
<h1>{{ snippets.index_title }}</h1>
<p>
{{ snippets.index_teaser }}
</p>
<div class="d-grid gap-3 d-md-block my-5">
<a href="#lernen" class="btn btn-primary btn-lg">{{ snippets.index_btn_start }}</a>
<a href="infos.html" class="btn btn-outline-secondary btn-lg">{{ snippets.index_btn_was_ist_afu }}</a>
</div>
<p>
<div class="alert alert-primary" role="alert">
{{ snippets.index_content }}
</div>
</p>
</div>
<div>
<div id="carouselExampleControls" class="carousel slide" data-bs-ride="carousel">
<div class="carousel-inner">
<div class="carousel-item active">
<img src="assets/images/hero/hero06.jpg" class="d-block w-100" alt="...">
<div class="position-absolute bottom-0 text-light w-100" style="background-color: rgba(0, 0, 0, 0.5)">
<p class="p-2 m-0 text-end">Foto: DK5WP df0alz.de</p>
</div>
</div>
<div class="carousel-item">
<img src="assets/images/hero/hero02.jpg" class="d-block w-100" alt="...">
<div class="position-absolute bottom-0 text-light w-100" style="background-color: rgba(0, 0, 0, 0.5)">
<p class="p-2 m-0 text-end">Foto: DK5WP df0alz.de</p>
</div>
</div>
<div class="carousel-item">
<img src="assets/images/hero/hero03.jpg" class="d-block w-100" alt="...">
<div class="position-absolute bottom-0 text-light w-100" style="background-color: rgba(0, 0, 0, 0.5)">
<p class="p-2 m-0 text-end">Foto: DK4HAA draussenfunker.de</p>
</div>
</div>
<div class="carousel-item">
<img src="assets/images/hero/hero01.jpg" class="d-block w-100" alt="...">
<div class="position-absolute bottom-0 text-light w-100" style="background-color: rgba(0, 0, 0, 0.5)">
<p class="p-2 m-0 text-end">Foto: DB8KN bei DL0JMU</p>
</div>
</div>
<div class="carousel-item">
<img src="assets/images/hero/hero04.jpg" class="d-block w-100" alt="...">
<div class="position-absolute bottom-0 text-light w-100" style="background-color: rgba(0, 0, 0, 0.5)">
<p class="p-2 m-0 text-end">Foto: DK4HAA draussenfunker.de</p>
</div>
</div>
<div class="carousel-item">
<img src="assets/images/hero/hero05.jpg" class="d-block w-100" alt="...">
<div class="position-absolute bottom-0 text-light w-100" style="background-color: rgba(0, 0, 0, 0.5)">
<p class="p-2 m-0 text-end">Foto: DO3OI</p>
</div>
</div>
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleControls" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="visually-hidden">Previous</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#carouselExampleControls" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</button>
</div>
</div>
</div>
<a name="lernen"></a>
<div class="row g-5 pt-5 mt-2 row-cols-1">
<div class="col col-lg-4">
<div class="feature col">
<div class="feature-icon bg-primary bg-gradient">
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48"><path d="M480-60q-72-68-165-104t-195-36v-440q101 0 194 36.5T480-498q73-69 166-105.5T840-640v440q-103 0-195.5 36T480-60Zm0-104q63-47 134-75t146-37v-276q-73 13-143.5 52.5T480-394q-66-66-136.5-105.5T200-552v276q75 9 146 37t134 75Zm0-436q-66 0-113-47t-47-113q0-66 47-113t113-47q66 0 113 47t47 113q0 66-47 113t-113 47Zm0-80q33 0 56.5-23.5T560-760q0-33-23.5-56.5T480-840q-33 0-56.5 23.5T400-760q0 33 23.5 56.5T480-680Zm0-80Zm0 366Z"/></svg>
</div>
<h2>Online lernen</h2>
<p>Bringe dir das nötige Wissen für die Amateurfunkprüfung einfach selber bei. Unser Lernmaterial hilft dir auf deinem Weg! Es gibt die drei <a href="infos.html">Klassen N, E und A</a>, die aufeinander aufbauen.</p>
<h5>Gesamtkurse</h5>
<p>Diese Kurse richten sich an alle, die noch kein Amateurfunkzeugnis haben.</p>
<div class="row row-cols-lg-3 g-2">
<div class="col"><a href="N_course_index.html" class="btn btn-outline-dark w-100">N<br><small>Neueinsteiger</small></a></div>
<div class="col"><a href="NE_course_index.html" class="btn btn-outline-dark w-100">N + E<br><small>Erweitert</small></a></div>
<div class="col"><a href="NEA_course_index.html" class="btn btn-outline-dark w-100">N + E + A<br><small>Alles</small></a></div>
</div>
<br>
<h5>Aufbaukurse</h5>
<p>Für alle, die schon über ein Amateurfunkzeugnis der Klasse N oder E verfügen, gibt es folgende Aufbaukurse:</p>
<div class="row row-cols-lg-3 g-2">
<div class="col"><a href="E_course_index.html" class="btn btn-outline-dark w-100">N -> E</a></div>
<div class="col"><a href="EA_course_index.html" class="btn btn-outline-dark w-100">N -> A</a></div>
<div class="col"><a href="A_course_index.html" class="btn btn-outline-dark w-100">E -> A</a></div>
</div>
<br>
<h5>Fragestunden</h5>
<p>Tauchen beim Selbststudium Fragen auf? Unsere ehrenamtlichen Helfer bieten für DARC-Mitglieder eine Fragestunde auf dem DARC-Videokonferenzserver an.</p>
<div class="row row-cols-lg-2">
<div class="col"><a href="https://treff.darc.de/d/#/teilnehmer/964LmqHw" class="btn btn-outline-dark w-100">Mittwochs 19:00</a></div>
<div class="col"><a href="https://treff.darc.de/d/#/teilnehmer/964LmqHw" class="btn btn-outline-dark w-100">Sonntags 18:00</a></div>
</div>
<br>
<h5>DARC Chat</h5>
<p>Der DARC e. V. betreibt eine eigene Matrix-Instanz. Dort gibt es Räume, in denen du deine Fragen stellen kannst (🌍 öffentlich, d. h. auch von anderen Matrix-Servern erreichbar, und 🔐 nur für Mitglieder):</p>
<div class="row row-cols-lg-3">
<div class="col"><a href="https://matrix.to/#/#ausbildung:darc.de" class="btn btn-outline-dark w-100">🌍 Ausbildung</a></div>
<div class="col"><a href="https://matrix.to/#/#Fragen_Technik:darc.de" class="btn btn-outline-dark w-100">🔐 Fragen T</a></div>
<div class="col"><a href="https://matrix.to/#/#Fragen_BV:darc.de" class="btn btn-outline-dark w-100">🔐 Fragen B+V</a></div>
</div>
<br>
<h5>Mitglied werden</h5>
<p>Der <a href="https://darc.de">DARC e. V.</a> unterstützt Dich auf deinem Weg zum Amateurfunkzeugnis und ist die größte Interessensvertretung der Funkamateure in Deutschland.</p>
<div class="row row-cols-lg-2">
<div class="col"><a href="https://www.darc.de/mitgliedschaft/mitglied-werden/" class="btn btn-outline-dark w-100">Mitglied Werden</a></div>
<div class="col"><a href="https://www.darc.de/mitgliedschaft/mitglied-werden/#c154065" class="btn btn-outline-dark w-100">Gastmitgliedschaft</a></div>
</div>
</div>
</div>
<div class="col col-lg-8 row g-5 pb-5 m-0 row-cols-1 row-cols-lg-2">
<div class="feature col">
<div class="feature-icon bg-primary bg-gradient">
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48" fill="#5f6368"><path d="m380-300 280-180-280-180v360ZM160-160q-33 0-56.5-23.5T80-240v-480q0-33 23.5-56.5T160-800h640q33 0 56.5 23.5T880-720v480q0 33-23.5 56.5T800-160H160Zm0-80h640v-480H160v480Zm0 0v-480 480Z"/></svg>
</div>
<h2>Videokurs Klasse N</h2>
<p>In Zusammenarbeit mit DL2YMR ist ein Videokurs für die Klasse N entstanden, der auf seinem YouTube-Kanal abrufbar ist.</p>
<div class="d-grid gap-2 d-md-block mb-5">
<a href="https://www.youtube.com/playlist?list=PLDpWnjHk5ERbcgpLPUaU0iTsD-wrmfENk" class="btn btn-primary">Zum Videokurs</a>
</div>
</div>
<div class="feature col">
<img style="float: right; width: 33%;" src="assets/images/darc-amateurfunklehrgang-klasse-n.jpg">
<div class="feature-icon bg-primary bg-gradient">
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 0 448 512" width="48"><path d="M96 0C43 0 0 43 0 96L0 416c0 53 43 96 96 96l288 0 32 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l0-64c17.7 0 32-14.3 32-32l0-320c0-17.7-14.3-32-32-32L384 0 96 0zm0 384l256 0 0 64L96 448c-17.7 0-32-14.3-32-32s14.3-32 32-32zm32-240c0-8.8 7.2-16 16-16l192 0c8.8 0 16 7.2 16 16s-7.2 16-16 16l-192 0c-8.8 0-16-7.2-16-16zm16 48l192 0c8.8 0 16 7.2 16 16s-7.2 16-16 16l-192 0c-8.8 0-16-7.2-16-16s7.2-16 16-16z"/></svg>
</div>
<h2>Buch Klasse N</h2>
<p>Die Lernhinhalte für die Klasse N gibt es auch als gedrucktes Buch. Es ist passend zum Online-Kurs ausgelegt.</p>
<div class="d-grid gap-2 d-md-block mb-5">
<a href="https://darcverlag.de/DARC-Amateurfunklehrgang-Klasse-N" class="btn btn-primary">Beim DARC-Verlag kaufen</a>
</div>
</div>
<div class="feature col">
<div class="feature-icon bg-primary bg-gradient">
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 0 640 512" width="48"><path d="M337.8 5.4C327-1.8 313-1.8 302.2 5.4L166.3 96 48 96C21.5 96 0 117.5 0 144L0 464c0 26.5 21.5 48 48 48l208 0 0-96c0-35.3 28.7-64 64-64s64 28.7 64 64l0 96 208 0c26.5 0 48-21.5 48-48l0-320c0-26.5-21.5-48-48-48L473.7 96 337.8 5.4zM96 192l32 0c8.8 0 16 7.2 16 16l0 64c0 8.8-7.2 16-16 16l-32 0c-8.8 0-16-7.2-16-16l0-64c0-8.8 7.2-16 16-16zm400 16c0-8.8 7.2-16 16-16l32 0c8.8 0 16 7.2 16 16l0 64c0 8.8-7.2 16-16 16l-32 0c-8.8 0-16-7.2-16-16l0-64zM96 320l32 0c8.8 0 16 7.2 16 16l0 64c0 8.8-7.2 16-16 16l-32 0c-8.8 0-16-7.2-16-16l0-64c0-8.8 7.2-16 16-16zm400 16c0-8.8 7.2-16 16-16l32 0c8.8 0 16 7.2 16 16l0 64c0 8.8-7.2 16-16 16l-32 0c-8.8 0-16-7.2-16-16l0-64zM232 176a88 88 0 1 1 176 0 88 88 0 1 1 -176 0zm88-48c-8.8 0-16 7.2-16 16l0 32c0 8.8 7.2 16 16 16l32 0c8.8 0 16-7.2 16-16s-7.2-16-16-16l-16 0 0-16c0-8.8-7.2-16-16-16z"/></svg>
</div>
<h2>Kurse vor Ort</h2>
<p>Einige unserer Ortsverbände bieten Präsenz- oder Onlinekurse mit erfahrenen Ausbildern an. Finde heraus, ob es einen für dich passenden Kurs bei dir in der Nähe gibt!</p>
<div class="d-grid gap-2 d-md-block mb-5">
<a href="kurse_vor_ort_karte.html" class="btn btn-primary">Präsenz</a>
<a href="kurse_vor_ort_liste.html" class="btn btn-primary">Online</a>
</div>
</div>
<div class="feature col">
<div class="feature-icon bg-primary bg-gradient">
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 0 448 512" width="48"><path d="M224 256A128 128 0 1 0 224 0a128 128 0 1 0 0 256zm-45.7 48C79.8 304 0 383.8 0 482.3C0 498.7 13.3 512 29.7 512l388.6 0c16.4 0 29.7-13.3 29.7-29.7C448 383.8 368.2 304 269.7 304l-91.4 0z"/></svg>
</div>
<h2>Ausbildungs&shy;paten</h2>
<p>Unsere Ausbildungspaten sind erfahrene Funkamateure, die dich gerne unterstützen. Sie können mit dir auch praktischen üben und nützliche Tipps für die Praxis geben.</p>
<div class="d-grid gap-2 d-md-block mb-5">
<a href="patenkarte.html" class="btn btn-primary">Zur Patenkarte</a>
</div>
</div>
<div class="feature col">
<div class="feature-icon bg-primary bg-gradient">
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 0 384 512" width="48"><path d="M192 0c-41.8 0-77.4 26.7-90.5 64L64 64C28.7 64 0 92.7 0 128L0 448c0 35.3 28.7 64 64 64l256 0c35.3 0 64-28.7 64-64l0-320c0-35.3-28.7-64-64-64l-37.5 0C269.4 26.7 233.8 0 192 0zm0 64a32 32 0 1 1 0 64 32 32 0 1 1 0-64zM105.8 229.3c7.9-22.3 29.1-37.3 52.8-37.3l58.3 0c34.9 0 63.1 28.3 63.1 63.1c0 22.6-12.1 43.5-31.7 54.8L216 328.4c-.2 13-10.9 23.6-24 23.6c-13.3 0-24-10.7-24-24l0-13.5c0-8.6 4.6-16.5 12.1-20.8l44.3-25.4c4.7-2.7 7.6-7.7 7.6-13.1c0-8.4-6.8-15.1-15.1-15.1l-58.3 0c-3.4 0-6.4 2.1-7.5 5.3l-.4 1.2c-4.4 12.5-18.2 19-30.6 14.6s-19-18.2-14.6-30.6l.4-1.2zM160 416a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z"/></svg>
</div>
<h2>Fragenkatalog</h2>
<p>Den Fragenkatalog mit den amtlichen Prüfungsfragen gibt es digital bei der <a href="https://50ohm.de/fk">Bundesnetzagentur</a>. Beim DARC-Verlag kann man auch eine gedruckte Version bestellen.</p>
<div class="d-grid gap-2 d-md-block mb-5">
<a href="https://darcverlag.de/Fragenkatalog-Klasse-N" class="btn btn-primary">Beim DARC-Verlag kaufen</a>
</div>
</div>
<div class="feature col">
<div class="feature-icon bg-primary bg-gradient">
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 0 384 512" width="48"><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M16 64C16 28.7 44.7 0 80 0L304 0c35.3 0 64 28.7 64 64l0 384c0 35.3-28.7 64-64 64L80 512c-35.3 0-64-28.7-64-64L16 64zM224 448a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zM304 64L80 64l0 320 224 0 0-320z"/></svg>
</div>
<h2>Trainings App</h2>
<p>Zum Trainieren der Fragen gibt es die 50Ohm App. Sie ist passend zum Online-Kurs ausgelegt.</p>
<div class="d-grid gap-2 d-md-block mb-5">
<a href="https://play.google.com/store/apps/details?id=de.darc.fuenfizigohm" class="btn btn-primary">Android</a>
<a href="https://apps.apple.com/de/app/50ohm/id6474642114" class="btn btn-primary">iOS</a>
</div>
</div>
</div>
</div>
<a rel="me" href="https://social.darc.de/@AJW"></a>
+53
View File
@@ -0,0 +1,53 @@
<div class="row flex-lg-row-reverse align-items-top g-5">
<div class="col-lg-7">
<iframe src="https://ajw.darc.de/lehrgangskarte/" width="100%" height="800px"></iframe>
</div>
<div class="col-lg-5">
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="index.html">Home</a></li>
<li class="breadcrumb-item"><a href="lernen.html">Lernen</a></li>
<li class="breadcrumb-item active" aria-current="page">Kurse vor Ort</li>
</ol>
</nav>
<h1>Kurse vor Ort</h1>
<p>Erfahrene Ausbilder halten &ndash; meist einmal in der Woche abends &ndash; Lektionen. Zwischen den Treffen solltest du selbständig den Lernstoff vertiefen und üben.</p>
<a class="btn btn-outline-secondary btn-sm px-4 gap-3" href="kurse_vor_ort_liste.html">Online-Kurse</a>
<hr class="col-md-12 mb-3">
<div><b>Ausbildungskurs</b></div>
<div class="d-grid gap-4 d-sm-flex mb-2 align-items-center">
<div class="d-grid gap-2 d-sm-flex mb-2 align-items-center">
<img src="https://ajw.darc.de/lehrgangskarte/img/Lehrgang-neu.png">
neu
</div>
<div class="d-grid gap-2 d-sm-flex mb-2 align-items-center">
<img src="https://ajw.darc.de/lehrgangskarte/img/Lehrgang-begonnen.png">
läuft
</div>
<div class="d-grid gap-2 d-sm-flex mb-2 align-items-center">
<img src="https://ajw.darc.de/lehrgangskarte/img/Lehrgang-jederzeit.png">
auf Anfrage
</div>
</div>
<div><b>Online-Kurs mit Präsenzanteil</b></div>
<div class="d-grid gap-4 d-sm-flex mb-2 align-items-center">
<div class="d-grid gap-2 d-sm-flex mb-2 align-items-center">
<img src="https://ajw.darc.de/lehrgangskarte/img/Online-neu.png">
neu
</div>
<div class="d-grid gap-2 d-sm-flex mb-2 align-items-center">
<img src="https://ajw.darc.de/lehrgangskarte/img/Online-begonnen.png">
läuft
</div>
</div>
</div>
</div>
+19
View File
@@ -0,0 +1,19 @@
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="index.html">Home</a></li>
<li class="breadcrumb-item"><a href="lernen.html">Lernen</a></li>
<li class="breadcrumb-item active" aria-current="page">Kurse vor Ort</li>
</ol>
</nav>
<h1>Kurse vor Ort</h1>
<p>Erfahrene Ausbilder halten &ndash; meist einmal in der Woche abends &ndash; Lektionen. Zwischen den Treffen solltest du selbständig den Lernstoff vertiefen und üben.</p>
<a class="btn btn-outline-secondary btn-sm px-4 gap-3" href="kurse_vor_ort_karte.html">Kartenansicht</a>
<hr class="col-md-12 mb-3">
<script src="https://darc.de/fileadmin/config/Resources/Public/JavaScript/tx_t3jquery/jquery-1.8.x-1.9.x-1.2.x.js?1619439474" type="text/javascript"></script>
<script id="onlinekurse" type="text/javascript" src="https://ajw.darc.de/lehrgangskarte/onlinelehrgaenge.js"></script>
+15 -4
View File
@@ -103,10 +103,21 @@
<hr>
</div>
{% endif %}
<div class="course">
{{ content }}
</div>
{% if sidebar == None %}
{% if course_wrapper == True %}
<div class="course">
{{ content }}
</div>
{% else %}
{{ content }}
{% endif %}
{% else %}
<div class="fiftyohm-content-2cols">
<div>{{ content }}</div>
<div>{{ sidebar }}</div>
</div>
{% endif %}
<footer class="text-lg-start border-top border-dark mt-5 pt-3">
<div class="d-flex flex-wrap justify-content-between gap-5 mb-5">
+19
View File
@@ -0,0 +1,19 @@
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="index.html">Home</a></li>
<li class="breadcrumb-item"><a href="lernen.html">Lernen</a></li>
<li class="breadcrumb-item active" aria-current="page">Ausbildungspaten</li>
</ol>
</nav>
<div class="row flex-lg-row-reverse align-items-top g-5 py-1">
<div class="col-lg-7">
<iframe src="https://ajw.darc.de/patenkarte/" width="100%" height="800px"></iframe>
</div>
<div class="col-lg-5">
<h1>Ausbildungspaten</h1>
<p>Die DARC-Ausbildungspaten sind erfahrene Funkamateure und helfen dir gerne beim Einstieg in den Amateurfunk. Sie beantworten Fragen, Helfen beim Lernen und können mit dir praktischen Ausbildungsfunk machen.</p>
</div>
</div>