Static CMS v2.0 (#226)

- [x] Update auf Static CMS v2.0
- [x] aktualisierte Shortcodes (schließt #225)
- [x] aktualisierte Previews (schließt #181)
- Ordnerunterstützung
- [x] vervollständigte Seiten
- [x] Aufräumarbeiten

Reviewed-on: #226
This commit is contained in:
2023-04-19 22:44:06 +02:00
parent 58c4c5abc7
commit 13dde42eb0
316 changed files with 2832 additions and 1978 deletions

View File

@ -0,0 +1,67 @@
import { Card, TextField } from "./components/index.js";
const AudioShortcode = {
label: "Audiodatei",
openTag: "{{< ",
closeTag: " >}}",
separator: " ",
toProps: (args) => {
if (args.length > 0) {
const src =
args
.find((arg) => arg.startsWith("src="))
?.split("=")[1]
.replaceAll('"', "") ?? "";
return { src: src };
}
return { src: "" };
},
toArgs: ({ src }) => {
return [`src=\"${src}\"`];
},
control: ({ src, onChange, controlProps }) => {
const { collection, field } = controlProps;
const handleChange = ({ path }) => {
onChange({ src: path });
};
const handleOpenMediaLibrary = useMediaInsert(
src,
{ collection, field },
handleChange
);
return Card([
TextField({
label: "Audiodatei",
value: src,
onChange: (event) => {
onChange({ src: event.target.value });
},
}),
h(
"span",
{ key: "audio-button", className: "flex gap-2 pt-2 px-2" },
h(
"button",
{
type: "button",
onClick: handleOpenMediaLibrary,
className: "btn btn-contained-primary",
},
"wählen"
)
),
]);
},
preview: ({ src }) => {
return h(
"div",
{ className: "card" },
h("audio", { src: src, controls: true })
);
},
};
export default AudioShortcode;

View File

@ -0,0 +1,75 @@
import { Card, TextField } from "./components/index.js";
const CardShortcode = {
label: "Link-Karte",
openTag: "{{< ",
closeTag: " >}}",
separator: " ",
toProps: (args) => {
if (args.length > 0) {
var title = "";
var link = "";
const linkIndex = args.findIndex((arg) => arg.startsWith('link="'));
const titleIndex = args.findIndex((arg) => arg.startsWith('title="'));
for (let arg of args.slice(titleIndex, linkIndex)) {
title += " " + arg.replaceAll("title=", "").replaceAll('"', "");
}
for (let arg of args.slice(linkIndex)) {
link += " " + arg.replaceAll("link=", "").replaceAll('"', "");
}
return { title: title.trim(), link: link.trim() };
}
return { title: "", link: "" };
},
toArgs: ({ title, link }) => {
return [`title=\"${title}\"`, `link=\"${link}\"`];
},
control: ({ title, link, onChange }) => {
return Card([
TextField({
label: "Titel",
value: title,
onChange: (event) => {
onChange({ title: event.target.value, link });
},
}),
TextField({
label: "Link",
value: link,
onChange: (event) => {
onChange({ title, link: event.target.value });
},
}),
]);
},
preview: ({ title, link }) => {
return h(
"div",
{ className: "container mb-0" },
h(
"div",
{ className: "card border-primary rounded-0 hover-shadow mb-5" },
h(
"div",
{ className: "card-body mb-0" },
h(
"h4",
{ className: "card-title" },
h("a", { className: "text-decoration-none", href: link }, title)
),
h(
"a",
{
className: "mb-0 btn btn-primary btn-sm text-decoration-none",
href: link,
},
"Mehr anzeigen"
)
)
)
);
},
};
export default CardShortcode;

View File

@ -0,0 +1,12 @@
const Card = (child, opts = { vertical: false }) =>
h(
"span",
{
className:
"relative flex border border-slate-400 focus-within:border-blue-800 dark:focus-within:border-blue-100 focus-within:bg-slate-100 dark:focus-within:bg-slate-800 hover:bg-slate-100 dark:hover:bg-slate-800 pb-3 cursor-text group/active" +
(opts.vertical ? " flex-col" : ""),
},
child
);
export default Card;

View File

@ -0,0 +1,41 @@
const Image = ({ label, assetSource, handleOpenMediaLibrary }) =>
h(
"span",
{ className: "flex flex-col w-full" },
h(
"label",
{
className:
"w-full flex text-xs font-bold dark:font-semibold group-focus-within/active:text-blue-500 group-hover/active:text-blue-500 cursor-text text-slate-500 dark:text-slate-400 px-3 pt-3",
},
label
),
h(
"span",
{ className: "flex flex-col gap-2 px-3 pt-2" },
h(
"span",
{},
h("img", {
role: "presentation",
src: assetSource,
className: "object-cover max-w-full overflow-hidden",
})
),
h(
"span",
{ className: "flex gap-2" },
h(
"button",
{
type: "button",
onClick: handleOpenMediaLibrary,
className: "btn btn-contained-primary",
},
"Bild auswählen"
)
)
)
);
export default Image;

View File

@ -0,0 +1,5 @@
import Card from "./card.js";
import TextField from "./text-field.js";
import Image from "./image.js";
export { Card, TextField, Image };

View File

@ -0,0 +1,21 @@
const TextField = ({ label, value, onChange }) =>
h(
"span",
{ key: "text-" + label, className: "flex flex-col w-full" },
h(
"label",
{
className:
"w-full flex text-xs font-bold dark:font-semibold group-focus-within/active:text-blue-500 group-hover/active:text-blue-500 cursor-text text-slate-500 dark:text-slate-400 px-3 pt-3",
},
label
),
h("input", {
className:
"MuiInout-Input w-full h-6 px-3 bg-transparent outline-none text-sm font-medium text-gray-900 dark:text-gray-100 cursor-default",
value,
onChange,
})
);
export default TextField;

View File

@ -0,0 +1,76 @@
import { Card, TextField } from "./components/index.js";
const DownloadShortcode = {
label: "Download-Karte",
openTag: "{{< ",
closeTag: " >}}",
separator: " ",
toProps: (args) => {
if (args.length > 0) {
var title = "";
var link = "";
const linkIndex = args.findIndex((arg) => arg.startsWith('link="'));
const titleIndex = args.findIndex((arg) => arg.startsWith('title="'));
for (let arg of args.slice(titleIndex, linkIndex)) {
title += " " + arg.replaceAll("title=", "").replaceAll('"', "");
}
for (let arg of args.slice(linkIndex)) {
link += " " + arg.replaceAll("link=", "").replaceAll('"', "");
}
return { title: title.trim(), link: link.trim() };
}
return { title: "", link: "" };
},
toArgs: ({ title, link }) => {
return [`title=\"${title}\"`, `link=\"${link}\"`];
},
control: ({ title, link, onChange }) => {
return Card([
TextField({
label: "Titel",
value: title,
onChange: (event) => {
onChange({ title: event.target.value, link });
},
}),
TextField({
label: "Download-Link",
value: link,
onChange: (event) => {
onChange({ title, link: event.target.value });
},
}),
]);
},
preview: ({ title, link }) => {
return h(
"div",
{ className: "container mb-0" },
h(
"div",
{ className: "card border-primary rounded-0 hover-shadow mb-5" },
h(
"div",
{ className: "card-body mb-0" },
h(
"h4",
{ className: "card-title" },
h("a", { className: "text-decoration-none", href: link }, title)
),
h(
"a",
{
className: "mb-0 btn btn-primary btn-sm text-decoration-none",
href: link,
},
h("i", { className: "mdi mdi-tray-arrow-down mb-0 me-2" }),
"Download"
)
)
)
);
},
};
export default DownloadShortcode;

View File

@ -0,0 +1,73 @@
import { Card, TextField } from "./components/index.js";
const GalleryShortcode = {
label: "Bildergallerie",
openTag: "{{< ",
closeTag: " >}}",
separator: " ",
toProps: (args) => {
if (args.length > 0) {
return {
dir:
args
.find((arg) => arg.startsWith("dir="))
?.split("=")[1]
.replaceAll('"', "") ?? "",
};
}
return { dir: "" };
},
toArgs: ({ dir }) => {
return [`dir=\"${dir}\"`];
},
control: ({ dir, onChange, controlProps }) => {
const { collection, field } = controlProps;
const handleChange = ({ path }) => {
onChange({ dir: path });
};
const handleOpenMediaLibrary = useMediaInsert(
dir,
{ collection, field, forFolder: true },
handleChange
);
return Card([
TextField({
label: "Gallerie-Ordner",
value: dir,
onChange: (event) => {
onChange({ dir: event.target.value });
},
}),
h(
"span",
{ key: "gallery-button", className: "flex gap-2 pt-2 px-2" },
h(
"button",
{
type: "button",
onClick: handleOpenMediaLibrary,
className: "btn btn-contained-primary",
},
"wählen"
)
),
]);
},
preview: ({ dir }) => {
return h(
"div",
{ className: "card mb-4" },
h(
"div",
{ className: "card-body mb-0" },
h("div", { className: "card-title h4" }, "Gallerie-Ordner"),
h("div", { className: "card-text" }, dir)
)
);
},
};
export default GalleryShortcode;

View File

@ -0,0 +1,64 @@
import { Card, Image } from "./components/index.js";
import { md5 } from "../previews/page-previews/components/index.js";
const ImageShortcode = {
label: "Bild",
openTag: "{{< ",
closeTag: " >}}",
separator: " ",
toProps: (args) => {
if (args.length > 0) {
return {
src:
args
.find((arg) => arg.startsWith("src="))
?.split("=")[1]
.replaceAll('"', "") ?? "",
};
}
return { src: "" };
},
toArgs: ({ src }) => {
return [`src=\"${src}\"`];
},
control: ({ src, onChange, controlProps }) => {
const { collection, field, entry } = controlProps;
const handleChange = ({ path }) => {
onChange({ src: path });
};
const handleOpenMediaLibrary = useMediaInsert(
src,
{ collection, field },
handleChange
);
const assetSource = useMediaAsset(src, collection, field, entry);
return Card(
Image({
label: "Bild",
assetSource,
handleOpenMediaLibrary,
})
);
},
preview: ({ src }) => {
return h(
"div",
{ className: "col-lg-3 col-md-4 col-sm-6" },
h(
"a",
{ className: "vb-gallery", "data-gall": md5(src) },
h("img", {
className: "img-thumbnail w-100 h-100",
style: { objectFit: "cover" },
src,
})
)
);
},
};
export default ImageShortcode;

View File

@ -0,0 +1,17 @@
import GalleryShortcode from "./gallery.js";
import ImageShortcode from "./image.js";
import DownloadShortcode from "./download.js";
import CardShortcode from "./card.js";
import YoutubeShortcode from "./youtube.js";
import AudioShortcode from "./audio.js";
import SliderShortcode from "./slider.js";
export {
GalleryShortcode,
ImageShortcode,
DownloadShortcode,
CardShortcode,
YoutubeShortcode,
AudioShortcode,
SliderShortcode,
};

View File

@ -0,0 +1,73 @@
import { Card, TextField } from "./components/index.js";
const SliderShortcode = {
label: "Bilderkarussell",
openTag: "{{< ",
closeTag: " >}}",
separator: " ",
toProps: (args) => {
if (args.length > 0) {
return {
dir:
args
.find((arg) => arg.startsWith("dir="))
?.split("=")[1]
.replaceAll('"', "") ?? "",
};
}
return { dir: "" };
},
toArgs: ({ dir }) => {
return [`dir=\"${dir}\"`];
},
control: ({ dir, onChange, controlProps }) => {
const { collection, field } = controlProps;
const handleChange = ({ path }) => {
onChange({ dir: path });
};
const handleOpenMediaLibrary = useMediaInsert(
dir,
{ collection, field, forFolder: true },
handleChange
);
return Card([
TextField({
label: "Bilderkarussell",
value: dir,
onChange: (event) => {
onChange({ dir: event.target.value });
},
}),
h(
"span",
{ key: "slider-button", className: "flex gap-2 pt-2 px-2" },
h(
"button",
{
type: "button",
onClick: handleOpenMediaLibrary,
className: "btn btn-contained-primary",
},
"wählen"
)
),
]);
},
preview: ({ dir }) => {
return h(
"div",
{ className: "card mb-4" },
h(
"div",
{ className: "card-body mb-0" },
h("div", { className: "card-title h4" }, "Bilderkarussell"),
h("div", { className: "card-text" }, dir)
)
);
},
};
export default SliderShortcode;

View File

@ -0,0 +1,59 @@
import { Card, TextField } from "./components/index.js";
const YoutubeShortcode = {
label: "YouTube-Video",
openTag: "{{< ",
closeTag: " >}}",
separator: " ",
toProps: (args) => {
if (args.length > 0) {
return { src: args[0] };
}
return { src: "" };
},
toArgs: ({ src }) => {
return [src];
},
control: ({ src, onChange }) => {
return Card(
[
TextField({
label: "YouTube-Video-ID",
value: src,
onChange: (event) => {
onChange({ src: event.target.value });
},
}),
h(
"iframe",
{
width: "100%",
height: "360",
src: `https://piped.kavin.rocks/embed/${src}`,
className: "px-3 pt-3",
},
""
),
],
{ vertical: true }
);
},
preview: ({ src }) => {
return h(
"span",
{},
h(
"iframe",
{
width: "420",
height: "315",
src: `https://piped.kavin.rocks/embed/${src}`,
},
""
)
);
},
};
export default YoutubeShortcode;