Artikel rendern slug für eventuelle Anker Links. Navigation vereinfacht und Item in eigene Komponente ausgelagert, um später schöner eine Multi-Level Navigation erstellen zu können. Label in Navigation-Collection umbenannt. Home-Page Komponente vereinfacht. Content-Komponente für eventuelles Animated-Ancher-Scrolling erweitert.
This commit is contained in:
parent
345ecb6177
commit
1bfa0d8b1b
@ -144,7 +144,7 @@ x-url: &url
|
|||||||
defaultValue: "default"
|
defaultValue: "default"
|
||||||
choices:
|
choices:
|
||||||
- { id: "default", name: "Gleicher Tab oder Seite (ohne Refresh)" }
|
- { id: "default", name: "Gleicher Tab oder Seite (ohne Refresh)" }
|
||||||
- { id: "_self", name: "Gleicher Tab oder Seite (Standardwert)" }
|
- { id: "_self", name: "Gleicher Tab oder Seite (mit Refresh)" }
|
||||||
- { id: "_blank", name: "Neuer Tab oder Fenster" }
|
- { id: "_blank", name: "Neuer Tab oder Fenster" }
|
||||||
- { id: "_parent", name: "Elternfenster" }
|
- { id: "_parent", name: "Elternfenster" }
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
import { _ } from "svelte-i18n"
|
import { _ } from "svelte-i18n"
|
||||||
import { Router, Route } from "svelte-routing"
|
import { Router, Route } from "svelte-routing"
|
||||||
import { scrollToTop } from "svelte-scrollto"
|
import { scrollToTop } from "svelte-scrollto"
|
||||||
import { location } from "../store"
|
import { location, generalInfo } from "../store"
|
||||||
|
|
||||||
import Home from "./routes/Home.svelte"
|
import Home from "./routes/Home.svelte"
|
||||||
import Content from "./routes/Content.svelte"
|
import Content from "./routes/Content.svelte"
|
||||||
@ -31,6 +31,33 @@
|
|||||||
if (typeof window !== "undefined") console.log("App initialized")
|
if (typeof window !== "undefined") console.log("App initialized")
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
{#if $generalInfo?.meta?.metaTitle}
|
||||||
|
<title>{$generalInfo?.meta?.metaTitle}</title>
|
||||||
|
{/if}
|
||||||
|
{#if $generalInfo?.meta?.metaDescription}
|
||||||
|
<meta name="description" content="{$generalInfo?.meta?.metaDescription}" />
|
||||||
|
{/if}
|
||||||
|
{#if $generalInfo?.meta?.metaKeywords}
|
||||||
|
<meta name="keywords" content="{$generalInfo?.meta?.metaKeywords.replaceAll(' ', '')}" />
|
||||||
|
{/if}
|
||||||
|
{#if $generalInfo?.person?.firstname || $generalInfo?.person?.lastname}
|
||||||
|
<meta
|
||||||
|
name="author"
|
||||||
|
content="{$generalInfo?.person?.firstname ? $generalInfo?.person?.firstname : ''} {$generalInfo?.person
|
||||||
|
?.lastname
|
||||||
|
? $generalInfo?.person?.lastname
|
||||||
|
: ''}"
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
|
{#if $generalInfo?.meta?.metaTagRobots && $generalInfo?.meta?.metaTagRobots.length}
|
||||||
|
<meta name="robots" content="{$generalInfo?.meta?.metaTagRobots}" />
|
||||||
|
{/if}
|
||||||
|
{#if $generalInfo?.media?.favicon}
|
||||||
|
<link rel="shortcut icon" type="image/x-icon" href="{$generalInfo?.media?.favicon.src}" />
|
||||||
|
{/if}
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
<Header />
|
<Header />
|
||||||
|
|
||||||
<Router url="{url}">
|
<Router url="{url}">
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { afterUpdate } from "svelte"
|
||||||
|
import * as animateScroll from "svelte-scrollto"
|
||||||
import { _ } from "svelte-i18n"
|
import { _ } from "svelte-i18n"
|
||||||
import { getContent, getArticles } from "../../api"
|
import { getContent, getArticles } from "../../api"
|
||||||
import { generalInfo, currentLang, location } from "../../store"
|
import { generalInfo, currentLang, location } from "../../store"
|
||||||
@ -67,6 +69,7 @@
|
|||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
loading = false
|
loading = false
|
||||||
|
scrollToAnchor()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,6 +106,7 @@
|
|||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
loading = false
|
loading = false
|
||||||
|
scrollToAnchor()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,6 +134,23 @@
|
|||||||
loadArticle()
|
loadArticle()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
afterUpdate(() => {
|
||||||
|
scrollToAnchor()
|
||||||
|
})
|
||||||
|
|
||||||
|
const scrollToAnchor = () => {
|
||||||
|
if (content && window.location.hash) {
|
||||||
|
window.setTimeout(() => {
|
||||||
|
animateScroll.scrollTo({
|
||||||
|
delay: 100,
|
||||||
|
element: window.location.hash,
|
||||||
|
offset: -200,
|
||||||
|
onDone: () => {},
|
||||||
|
})
|
||||||
|
}, 500)
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
|
@ -1,44 +1,14 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import * as animateScroll from "svelte-scrollto"
|
import * as animateScroll from "svelte-scrollto"
|
||||||
|
|
||||||
import { generalInfo } from "../../store"
|
// import { generalInfo } from "../../store"
|
||||||
|
|
||||||
// import ContactForm from "../widgets/ContactForm.svelte"
|
// import ContactForm from "../widgets/ContactForm.svelte"
|
||||||
// import GoogleMaps from "../widgets/GoogleMaps.svelte"
|
// import GoogleMaps from "../widgets/GoogleMaps.svelte"
|
||||||
import ScrollTo from "../widgets/ScrollTo.svelte"
|
// import GeneralMediaImage from "../widgets/GeneralMediaImage.svelte"
|
||||||
import GeneralMediaImage from "../widgets/GeneralMediaImage.svelte"
|
|
||||||
import ArticlesList from "../widgets/ArticlesList.svelte"
|
import ArticlesList from "../widgets/ArticlesList.svelte"
|
||||||
|
|
||||||
let expandedForm: string = "recipe"
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
|
||||||
{#if $generalInfo?.meta?.metaTitle}
|
|
||||||
<title>{$generalInfo?.meta?.metaTitle}</title>
|
|
||||||
{/if}
|
|
||||||
{#if $generalInfo?.meta?.metaDescription}
|
|
||||||
<meta name="description" content="{$generalInfo?.meta?.metaDescription}" />
|
|
||||||
{/if}
|
|
||||||
{#if $generalInfo?.meta?.metaKeywords}
|
|
||||||
<meta name="keywords" content="{$generalInfo?.meta?.metaKeywords.replaceAll(' ', '')}" />
|
|
||||||
{/if}
|
|
||||||
{#if $generalInfo?.person?.firstname || $generalInfo?.person?.lastname}
|
|
||||||
<meta
|
|
||||||
name="author"
|
|
||||||
content="{$generalInfo?.person?.firstname ? $generalInfo?.person?.firstname : ''} {$generalInfo?.person
|
|
||||||
?.lastname
|
|
||||||
? $generalInfo?.person?.lastname
|
|
||||||
: ''}"
|
|
||||||
/>
|
|
||||||
{/if}
|
|
||||||
{#if $generalInfo?.meta?.metaTagRobots && $generalInfo?.meta?.metaTagRobots.length}
|
|
||||||
<meta name="robots" content="{$generalInfo?.meta?.metaTagRobots}" />
|
|
||||||
{/if}
|
|
||||||
{#if $generalInfo?.media?.favicon}
|
|
||||||
<link rel="shortcut icon" type="image/x-icon" href="{$generalInfo?.media?.favicon.src}" />
|
|
||||||
{/if}
|
|
||||||
</svelte:head>
|
|
||||||
|
|
||||||
<ArticlesList pages="{['/']}" />
|
<ArticlesList pages="{['/']}" />
|
||||||
|
|
||||||
<!-- <GeneralMediaImage id="test1" /> -->
|
<!-- <GeneralMediaImage id="test1" /> -->
|
||||||
@ -46,17 +16,3 @@
|
|||||||
<!-- <ContactForm type="recipe" collapsed="{expandedForm !== 'recipe'}" /> -->
|
<!-- <ContactForm type="recipe" collapsed="{expandedForm !== 'recipe'}" /> -->
|
||||||
<!-- <ContactForm type="contact" collapsed="{expandedForm !== 'contact'}" /> -->
|
<!-- <ContactForm type="contact" collapsed="{expandedForm !== 'contact'}" /> -->
|
||||||
<!-- <GoogleMaps /> -->
|
<!-- <GoogleMaps /> -->
|
||||||
|
|
||||||
<ScrollTo
|
|
||||||
on:scrollTo="{(e) => {
|
|
||||||
expandedForm = null
|
|
||||||
animateScroll.scrollTo({
|
|
||||||
delay: 100,
|
|
||||||
element: '#' + e.detail.element,
|
|
||||||
offset: -200,
|
|
||||||
onDone: () => {
|
|
||||||
expandedForm = e.detail.element
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}}"
|
|
||||||
/>
|
|
||||||
|
@ -66,7 +66,10 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if article && published}
|
{#if article && published}
|
||||||
<article class="{cssClass} {article?.layout?.variant} {marginClasses} {paddingClasses}">
|
<article
|
||||||
|
class="{cssClass} {article?.layout?.variant} {marginClasses} {paddingClasses}"
|
||||||
|
id="{article?.content?.slug}"
|
||||||
|
>
|
||||||
{#if article?.layout?.variant === "top"}
|
{#if article?.layout?.variant === "top"}
|
||||||
{#if article?.content?.types?.media?.files?.length}
|
{#if article?.content?.types?.media?.files?.length}
|
||||||
<TibiArticleMediaFile
|
<TibiArticleMediaFile
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import * as animateScroll from "svelte-scrollto"
|
|
||||||
import Icon from "mdi-svelte"
|
import Icon from "mdi-svelte"
|
||||||
import { mdiMenu } from "@mdi/js"
|
import { mdiMenu } from "@mdi/js"
|
||||||
|
|
||||||
import { links, link } from "svelte-routing"
|
import { navigations, currentLang } from "../../store"
|
||||||
import { navigations, currentLang, location } from "../../store"
|
|
||||||
|
|
||||||
import LanguageChooser from "./LanguageChooser.svelte"
|
import LanguageChooser from "./LanguageChooser.svelte"
|
||||||
|
import NavigationItem from "./NavigationItem.svelte"
|
||||||
|
|
||||||
export let ident = "main"
|
export let ident = "main"
|
||||||
|
|
||||||
@ -26,36 +25,9 @@
|
|||||||
<LanguageChooser />
|
<LanguageChooser />
|
||||||
|
|
||||||
{#if navigation}
|
{#if navigation}
|
||||||
<nav class="{ident}" use:links>
|
<nav class="{ident}">
|
||||||
{#each navigation?.items || [] as item}
|
{#each navigation?.items || [] as item}
|
||||||
{#if !item.settings.url.hidden}
|
<NavigationItem item="{item}" />
|
||||||
{#if item.settings.url.url}
|
|
||||||
{#if item.settings.url.target === "default"}
|
|
||||||
<a
|
|
||||||
use:link
|
|
||||||
href="{item.settings.url.url}"
|
|
||||||
class:active="{'/' + item.settings.page === $location.path}"
|
|
||||||
>
|
|
||||||
{item.settings.title}
|
|
||||||
</a>
|
|
||||||
{:else}
|
|
||||||
<a
|
|
||||||
href="{item.settings.url.url}"
|
|
||||||
target="{item.settings.url.target}"
|
|
||||||
on:click="{() => {
|
|
||||||
animateScroll.scrollTo({ element: item.settings.url.url, offset: -200 })
|
|
||||||
showMobileNav = false
|
|
||||||
}}"
|
|
||||||
>
|
|
||||||
{item.settings.title}
|
|
||||||
</a>
|
|
||||||
{/if}
|
|
||||||
{:else}
|
|
||||||
<a href="{item.settings.page + '/'}" class:active="{'/' + item.settings.page === $location.path}">
|
|
||||||
{item.settings.title}
|
|
||||||
</a>
|
|
||||||
{/if}
|
|
||||||
{/if}
|
|
||||||
{/each}
|
{/each}
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
@ -64,44 +36,9 @@
|
|||||||
<Icon path="{mdiMenu}" size="2" />
|
<Icon path="{mdiMenu}" size="2" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<nav class="{ident}-mobile" class:show="{showMobileNav}" use:links>
|
<nav class="{ident}-mobile" class:show="{showMobileNav}">
|
||||||
{#each navigation?.items || [] as item}
|
{#each navigation?.items || [] as item}
|
||||||
{#if !item.settings.url.hidden}
|
<NavigationItem item="{item}" />
|
||||||
{#if item.settings.url.url}
|
|
||||||
{#if item.settings.url.target === "default"}
|
|
||||||
<a
|
|
||||||
use:link
|
|
||||||
href="{item.settings.url.url}"
|
|
||||||
class:active="{'/' + item.settings.page === $location.path}"
|
|
||||||
>
|
|
||||||
{item.settings.title}
|
|
||||||
</a>
|
|
||||||
{:else}
|
|
||||||
<div class="nav-item">
|
|
||||||
<a
|
|
||||||
href="{item.settings.url.url}"
|
|
||||||
target="{item.settings.url.target}"
|
|
||||||
on:click="{() => {
|
|
||||||
animateScroll.scrollTo({ element: item.settings.url.url, offset: -200 })
|
|
||||||
showMobileNav = false
|
|
||||||
}}"
|
|
||||||
>
|
|
||||||
{item.settings.title}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
{:else}
|
|
||||||
<div class="nav-item">
|
|
||||||
<a
|
|
||||||
href="{item.settings.page + '/'}"
|
|
||||||
on:click="{() => (showMobileNav = false)}"
|
|
||||||
class:active="{'/' + item.settings.page === $location.path}"
|
|
||||||
>
|
|
||||||
{item.settings.title}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
{/if}
|
|
||||||
{/each}
|
{/each}
|
||||||
</nav>
|
</nav>
|
||||||
{/if}
|
{/if}
|
||||||
|
63
src/components/widgets/NavigationItem.svelte
Normal file
63
src/components/widgets/NavigationItem.svelte
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
// import * as animateScroll from "svelte-scrollto"
|
||||||
|
import { link, navigate } from "svelte-routing"
|
||||||
|
import { location } from "../../store"
|
||||||
|
|
||||||
|
export let item: NavigationItem
|
||||||
|
|
||||||
|
const isActive = (itemPath: string, locationPath: string): boolean | any => {
|
||||||
|
itemPath = "/" + itemPath + (locationPath.endsWith("/") ? "/" : "")
|
||||||
|
locationPath = (locationPath.startsWith("/") ? "" : "/") + locationPath
|
||||||
|
|
||||||
|
if (!locationPath.endsWith("/")) {
|
||||||
|
return locationPath.startsWith(itemPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
return itemPath === locationPath
|
||||||
|
}
|
||||||
|
|
||||||
|
const onClickInternalLink = (item: NavigationItem) => {
|
||||||
|
let url = ""
|
||||||
|
if (item.settings?.page) {
|
||||||
|
url += item.settings?.page
|
||||||
|
}
|
||||||
|
if (item.settings?.url?.url) {
|
||||||
|
url += (url.endsWith("/") ? "" : "/") + item.settings.url.url
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.settings?.page) {
|
||||||
|
navigate(url, { replace: true })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getInternalUrl = (item): string => {
|
||||||
|
if (item.settings.page === "/") {
|
||||||
|
return item.settings.page
|
||||||
|
}
|
||||||
|
|
||||||
|
return item.settings.page + "/"
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if !item.settings.url.hidden}
|
||||||
|
{#if item.settings.url.url}
|
||||||
|
{#if item.settings.url.target === "default"}
|
||||||
|
<a
|
||||||
|
use:link
|
||||||
|
href="{getInternalUrl(item)}"
|
||||||
|
class:active="{isActive(item.settings.page, $location.path)}"
|
||||||
|
on:click|stopPropagation="{() => onClickInternalLink(item)}"
|
||||||
|
>
|
||||||
|
{item.settings.title}
|
||||||
|
</a>
|
||||||
|
{:else}
|
||||||
|
<a href="{item.settings.url.url}" target="{item.settings.url.target}">
|
||||||
|
{item.settings.title}
|
||||||
|
</a>
|
||||||
|
{/if}
|
||||||
|
{:else}
|
||||||
|
<a use:link href="{getInternalUrl(item)}" class:active="{isActive(item.settings.page, $location.path)}">
|
||||||
|
{item.settings.title}
|
||||||
|
</a>
|
||||||
|
{/if}
|
||||||
|
{/if}
|
@ -29,11 +29,8 @@ article,
|
|||||||
|
|
||||||
.article-details {
|
.article-details {
|
||||||
&.default {
|
&.default {
|
||||||
background: #000;
|
|
||||||
color: #fff;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.news {
|
&.news {
|
||||||
background: #fc0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,8 @@ header {
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
transition: @transition-default;
|
transition: @transition-default;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
border: 1px solid @primary;
|
||||||
|
padding: 0 @space-xs;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: @primary;
|
color: @primary;
|
||||||
|
Loading…
Reference in New Issue
Block a user