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:
Mario Linz 2022-07-08 14:44:23 +02:00
parent 345ecb6177
commit 1bfa0d8b1b
9 changed files with 127 additions and 121 deletions

View File

@ -144,7 +144,7 @@ x-url: &url
defaultValue: "default"
choices:
- { 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: "_parent", name: "Elternfenster" }

View File

@ -2,7 +2,7 @@
import { _ } from "svelte-i18n"
import { Router, Route } from "svelte-routing"
import { scrollToTop } from "svelte-scrollto"
import { location } from "../store"
import { location, generalInfo } from "../store"
import Home from "./routes/Home.svelte"
import Content from "./routes/Content.svelte"
@ -31,6 +31,33 @@
if (typeof window !== "undefined") console.log("App initialized")
</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 />
<Router url="{url}">

View File

@ -1,4 +1,6 @@
<script lang="ts">
import { afterUpdate } from "svelte"
import * as animateScroll from "svelte-scrollto"
import { _ } from "svelte-i18n"
import { getContent, getArticles } from "../../api"
import { generalInfo, currentLang, location } from "../../store"
@ -67,6 +69,7 @@
})
.finally(() => {
loading = false
scrollToAnchor()
})
}
@ -103,6 +106,7 @@
})
.finally(() => {
loading = false
scrollToAnchor()
})
}
@ -130,6 +134,23 @@
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>
<svelte:head>

View File

@ -1,44 +1,14 @@
<script lang="ts">
import * as animateScroll from "svelte-scrollto"
import { generalInfo } from "../../store"
// import { generalInfo } from "../../store"
// import ContactForm from "../widgets/ContactForm.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"
let expandedForm: string = "recipe"
</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="{['/']}" />
<!-- <GeneralMediaImage id="test1" /> -->
@ -46,17 +16,3 @@
<!-- <ContactForm type="recipe" collapsed="{expandedForm !== 'recipe'}" /> -->
<!-- <ContactForm type="contact" collapsed="{expandedForm !== 'contact'}" /> -->
<!-- <GoogleMaps /> -->
<ScrollTo
on:scrollTo="{(e) => {
expandedForm = null
animateScroll.scrollTo({
delay: 100,
element: '#' + e.detail.element,
offset: -200,
onDone: () => {
expandedForm = e.detail.element
},
})
}}"
/>

View File

@ -66,7 +66,10 @@
</script>
{#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?.content?.types?.media?.files?.length}
<TibiArticleMediaFile

View File

@ -1,12 +1,11 @@
<script lang="ts">
import * as animateScroll from "svelte-scrollto"
import Icon from "mdi-svelte"
import { mdiMenu } from "@mdi/js"
import { links, link } from "svelte-routing"
import { navigations, currentLang, location } from "../../store"
import { navigations, currentLang } from "../../store"
import LanguageChooser from "./LanguageChooser.svelte"
import NavigationItem from "./NavigationItem.svelte"
export let ident = "main"
@ -26,36 +25,9 @@
<LanguageChooser />
{#if navigation}
<nav class="{ident}" use:links>
<nav class="{ident}">
{#each navigation?.items || [] as item}
{#if !item.settings.url.hidden}
{#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}
<NavigationItem item="{item}" />
{/each}
</nav>
@ -64,44 +36,9 @@
<Icon path="{mdiMenu}" size="2" />
</div>
<nav class="{ident}-mobile" class:show="{showMobileNav}" use:links>
<nav class="{ident}-mobile" class:show="{showMobileNav}">
{#each navigation?.items || [] as item}
{#if !item.settings.url.hidden}
{#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}
<NavigationItem item="{item}" />
{/each}
</nav>
{/if}

View 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}

View File

@ -29,11 +29,8 @@ article,
.article-details {
&.default {
background: #000;
color: #fff;
}
&.news {
background: #fc0;
}
}

View File

@ -56,6 +56,8 @@ header {
text-decoration: none;
transition: @transition-default;
font-weight: 500;
border: 1px solid @primary;
padding: 0 @space-xs;
&:hover {
color: @primary;