diff --git a/api/collections/democol.yml b/api/collections/democol.yml index 706fd45..5e195dd 100644 --- a/api/collections/democol.yml +++ b/api/collections/democol.yml @@ -17,8 +17,10 @@ fields: # Auf die möglichen Definitionen wird im Kapitel "fields" # eingegangen. - !include fields/title.yml - - !include fields/date.yml - !include fields/type.yml + - !include fields/date.yml + - !include fields/content.yml + - !include fields/info.yml # Neben der Definition der Indexe innerhalbd des Feld-Objektes selbst, # ist die Index-Definition global für die Kollektion auch hier möglich. @@ -26,8 +28,8 @@ fields: # Außerdem sind hier feinere Einstellungen für den Index möglich. # Mehr dazu im "indexes" Kapitel -indexes: - - !include democol/textindex.yml +# indexes: + # - !include democol/textindex.yml # Standardsprache für Text-Index in der Datenbank defaultLanguage: de @@ -90,7 +92,7 @@ hooks: # aktualisiert wird. update: type: javascript - file: hooks/democol/put_create.js + file: hooks/democol/put_update.js # "return" wird auch hier vor der Serverantwort ausgeführt. return: type: javascript diff --git a/api/collections/democol/meta.yml b/api/collections/democol/meta.yml index 220994f..8bf43ff 100644 --- a/api/collections/democol/meta.yml +++ b/api/collections/democol/meta.yml @@ -38,13 +38,37 @@ subNavigation: - # Jede Unternavigation braucht einen eindeutigen Namen um diese später # in z.B. Javascript-Code wieder erkennen zu können. name: pages + + # Die Angabe des "label" ist optional. Wird sie nicht angegeben, wird + # wird diese Unternavigation nicht in der Navigation angezeigt. + # Ohne "label" kann die Unternavigation aber weiterhin für die Referenzierung + # z.B. in der Mediathek-Ansicht des ContentBuilders verwendet werden. label: de: Seiten en: Pages + muiIcon: page-layout-body + defaultSort: field: titel order: ASC + + # Standardmäßig wird man beim Klick auf einen Eintrag der Kollektion + # (z.B. Zeile in der Tabelle) direkt zum Editieren des Datensatzes weitergeleitet. + # Möchte man das nicht, so kann hier ein alternatives Verhalten definiert werden. + # Mögliche Werte sind: + # - "edit" (Standard) + # - "view" (Anzeigen des Datensatzes) + # - Objekt mit "eval"-Attribut + # + # Beim Objekt mit "eval"-Attribut wird der Code mit dem Javascript-Kontext für + # Kollektionen im tibi-admin ausgeführt. Das Ergebnis kann hierbei wieder "edit" + # oder "view" sein. + # Außerdem ist es möglich, eine eigene Funktion zu definieren, die den Datensatz + # als Parameter erhält. Diese Funktion wird dann für den jweiligen Datensatz + # ausgeführt, auf den geklickt wurde. Mehr dazu unter dem Widget "ContentBuilder". + defaultCallback: view + views: - !include simpleList.yml - !include table.yml @@ -63,6 +87,7 @@ subNavigation: defaultSort: field: date order: DESC + defaultCallback: edit views: - !include simpleList.yml - !include table.yml @@ -74,4 +99,4 @@ subNavigation: # Um diese Anordnung in Tabs zu strukturieren, ist die Verwendung von "tablist" # vorgesehen. # Die Definition befindet sich in einem gesonderten Kapitel -tablist: !include democol/tablist.yml \ No newline at end of file +tablist: !include tablist.yml \ No newline at end of file diff --git a/api/collections/democol/tablist.yml b/api/collections/democol/tablist.yml index 4bf71c4..541e8e6 100644 --- a/api/collections/democol/tablist.yml +++ b/api/collections/democol/tablist.yml @@ -14,11 +14,18 @@ tabs: # Welche Felder dieser Tab anzeigen soll, wird über "subFields" # beschrieben. subFields: + - source: type - source: title - source: date - - name: meta + - name: content label: - de: Metaangaben - en: Meta data + de: Inhalt + en: Content subFields: - - source: meta.author + - source: content + - name: info + label: + de: Informationen + en: Information + subFields: + - source: info diff --git a/api/collections/fields/content.yml b/api/collections/fields/content.yml new file mode 100644 index 0000000..6fbd607 --- /dev/null +++ b/api/collections/fields/content.yml @@ -0,0 +1,113 @@ +# Der Name des Feldes ist natürlich beliebig wählbar. +name: content + +# "string" als Datentyp ist zwingend. +type: string + +meta: + label: + de: Inhalt + en: content + + # Die Bezeichnung des ContentBuilder-Widgets ist "contentbuilder". + widget: contentbuilder + + # Die Anzeige des ContentBuilder im tibi-admin geschieht innerhalb + # eines iframes. Das ist notwendig, da der ContentBuilder eigene + # Styles mitbringet, die sich nicht mit den Styles des tibi-admin + # vermischen sollten. + + # Via "baseHref" wird der -Tag im iframe gesetzt. + # somit können alle relativen Pfade im ContentBuilder (z.B. Bilder) + # aufgelöst werden. + # Wie man hier sieht, ist die Angabe via "eval" mittels möglich. + # Der Kontext ist auf Feldebene, wie bei "dependsOn" und "defaultValue". + # Alternativ kann die Angabe auch direkt als String erfolgend. + # Dann natürlich ohne die Evaluierung der Variable "$projectBase", wie hier. + baseHref: + eval: $projectBase + + # Sollen weitere CSS-Datei in das iframe geladen werden, können diese + # hier aufgelistet werden. + # Die Angabe kann direkt als Array erfolgen oder via "eval", dessen + # Code das Array der Strings mit den Dateipfaden zurückgibt. + # Auch zu beachten ist hier die relative Angabe. Da "baseHref" gesetzt + # ist, wird der Pfad relativ zu dieser Projekt-Basis innerhalb des + # tibi-server aufgelöst. + # Die Auslieferung der CSS-Dateien direkt über den tibi-server kann + # nur funktionieren, wenn "_dist_" in der "assets" Konfiguration der + # "config.yml" definiert ist. + cssHref: + - _/assets/_dist_/index.css + + # Um eine Kollektion stellvertretend als Mediathek anzubinden, sind die + # Angaben unter "imageSelect", "fileSelect" und "videoSelect" zu tätigen. + # "imageSelect" betrifft die Einbindung von Bildern, "fileSelect" die + # Einbindung von Dateien, "videoSelect" die Einbindung von Videos. + imageSelect: + + # Die Angabe "collection" ist zwingend. Hier wird die Kollektion + # definiert, die als Sammlung für die Bilder/Datei dient. + # Der Aufbau der Kollektion ist dabei frei, solange ein Upload-Feld + # für die Dateien existiert, welches die URL zur Datei zurückgibt. + collection: medialib + + # Optional kann ein Filter und View für die Einbindung der Bilder/Dateien + # definiert werden. Dies geschieht über einen "subNavigation" + # Eintrag innerhalb des "meta.subNavigation" Arrays, der Kollektion + # (hier bei "medialib"). + # Die Angabe hier ist die auszuwählende Navigation per Index des Arrays. + subNavigation: 0 + + fileSelect: + collection: medialib + subNavigation: 0 + videoSelect: + collection: medialib + subNavigation: 0 + + # "customTags" des ContentBuilder können verwendet werden um die Einbindung + # von Modulen ins HTML zu ermöglichen. + # Die folgende Auflistung ist dabei ein Beispiel für ein Modul. + customTags: + + - # Der Platzhalter wird 1:1 ins HTML übernommen und ist dabei frei + # definierbar. + # Die eigentliche Funktion eines Modul-Systems muss dann später + # im Frontend implementiert werden. + placeholder: "Mein Modul" + + # Die Benennung für die UI des ContentBuilder geschieht über die + # "label" Angabe, die mehrsprachig erfolgen kann. + label: + de: "Mein Modul" + en: "My Module" + + # Um direkt Style-Angaben in das iframe des ContentBuilder zu übernehmen, + # werden diese hier angegeben. + # Natürlich ist auch hier wieder die Angabe via "eval" möglich. + # Nachfolgendes Beispiel erzeugt im ContentBuilder eine deutliche Darstellung + # des eingebundenen Moduls. + style: | + /*css*/ + .tibi-module { + padding: 10px; + border: 3px dashed #c4c4c4; + display: block; + text-align: center; + font-size: 14px; + color: black; + } + .tibi-module::before { + content: "\1F5BD "; + font-size: 16px; + color: black; + } + .tibi-module::after { + content: " title=\"" attr(title) "\" description=\"" attr(description) "\""; + font-size: 10px; + color: #555; + display: block; + padding-top: 5px; + } + /*!css*/ \ No newline at end of file diff --git a/api/collections/fields/date.yml b/api/collections/fields/date.yml index 9065b7b..b21d4b8 100644 --- a/api/collections/fields/date.yml +++ b/api/collections/fields/date.yml @@ -38,7 +38,7 @@ meta: # Abgelkeitet vom "type" gibt es Standard-Widgets. für spezielle # Aufgaben stehen aber eine Hand voll Widgets bereit, die später # beschrieben werden. - widget: text + widget: date # Standardwerte für neue Enträge können entweder direkt angegeben # werden oder via Javascript client-seitig generiert werden. @@ -54,4 +54,4 @@ meta: # Das Feld wird nur eingeblendet wenn der Wert von "type" # (auf gleicher Ebene wie das Feld "date" selbst) # gleich "news" ist. - eval: $parent.type == "news" + eval: $parent?.type == "news" diff --git a/api/collections/fields/info.yml b/api/collections/fields/info.yml new file mode 100644 index 0000000..4fa3c9a --- /dev/null +++ b/api/collections/fields/info.yml @@ -0,0 +1,13 @@ +name: info +type: object +meta: + label: + de: Info + en: Info +subFields: + - name: author + type: string + meta: + label: + de: Autor + en: Author diff --git a/api/collections/fields/title.yml b/api/collections/fields/title.yml index e69de29..d7531d7 100644 --- a/api/collections/fields/title.yml +++ b/api/collections/fields/title.yml @@ -0,0 +1,6 @@ +name: title +type: string +meta: + label: + de: Titel + en: Title diff --git a/api/collections/fields/type.yml b/api/collections/fields/type.yml index e69de29..cc6e752 100644 --- a/api/collections/fields/type.yml +++ b/api/collections/fields/type.yml @@ -0,0 +1,16 @@ +name: type +type: string +meta: + label: + de: Typ + en: Type + widget: select + choices: + - name: + de: Standardseite + en: Standard page + id: page + - name: + de: News + en: News + id: news diff --git a/api/collections/medialib.yml b/api/collections/medialib.yml new file mode 100644 index 0000000..1efdf0e --- /dev/null +++ b/api/collections/medialib.yml @@ -0,0 +1,100 @@ +# Der Name der Kollektion ist beliebig, aber wird in unserem +# Beispiel vom ContentBuilder als "medialib" referenziert. +name: medialib +uploadPath: ../media/medialib + +fields: + - !include fields/title.yml + + # Ein Feld vom Typ "file" wird für die Mediathek natürlich + # benötigt. + - name: file + type: file + meta: + label: + de: Datei + en: File + +permissions: + public: + methods: + get: true + post: false + put: false + delete: false + user: + methods: + get: true + post: true + put: true + delete: true + +meta: + label: + de: Medienbibliothek + en: Media Library + muiIcon: multimedia + defaultSort: + field: title + order: ASC + + # "defaultImageFilter" dient auch hier nur zur Reduzierung der + # Bildgröße bei der Anzeige im tibi-admin (Listen). + # Die Bildgröße für die Einbindung ins erzeugte HTML des ContentBuilder + # hat hiermit nix zu tun. + defaultImageFilter: s + + # Wird unter "image-/file-/videoSelect" im ContentBuilder Feld kein + # "subNavigation" Index definiert, werden auch folgende "views" + # verwendet. + views: + - type: table + mediaQuery: "(min-width: 0px)" + columns: + - source: updateTime + label: letztes Update + type: datetime + - source: title + filter: true + - source: file + + # Wird ein "subNavigation" Index für "image-/file-/videoSelect" definiert, + # wird die entsprechende Navigation aus folgender Liste angesprochen. + # "0" ist dabei der Index für das erste Element dieser Liste. + subNavigation: + - # Der "name" der Navigation ist für die Mediathek nicht von Bedeutung, + # kann aber für "eval"-Code interessant sein. + name: modal + + # Auf "label" wurde hier verzichtet, damit dieses Element nicht in der + # Hauptnavigation des tibi-admin auftaucht. + + # Folgende Ansicht wird für unsere Auswahl der Datei im ContentBuilder + # angeboten. + views: + - type: table + mediaQuery: "(min-width: 0px)" + columns: + - source: title + filter: true + - source: file + + # Damit der ContentBuilder weiß, welche Datei ausgewählt wurde, ist + # ist folgender "defaultCallback" notwendig. + # Die Funktion wird beim Klick auf die entsprechende Datei aufgerufen. + # Als Funktionsparameter steht der gesamte Datensatz der Auswahl zur + # Verfügung. + # Die Funktionen "parent.selectAsset" und "parent.focus" sind ContentBuilder + # spezifisch und schließen die Listenansicht direkt nach Übergabe der + # Datei-URL. + # Die URL setzt sich aus dem Pfad zur Datei und dem Filter "l" zusammen. + # Es wurde eine relative URL konstruiert, da das ContentBuilder-Widget + # mit "baseHref" zur Projekt-URL erstellt wird. + defaultCallback: + eval: | + //js + (entry) => { + parent.selectAsset("medialib/" + entry.id + "/" + entry.file?.src + "?filter=l") + parent.focus() + } + //!js diff --git a/api/config.yml b/api/config.yml index ff98d8c..a3ad37f 100644 --- a/api/config.yml +++ b/api/config.yml @@ -9,28 +9,29 @@ namespace: demo # Das "meta"-Objekt ist frei definierbar, wird aber vom tibi-admin in spezieller Form erwartet. # Mögliche Angaben, die der tibi-admin versteht, sind hier mit aufgeführt. meta: - # Pfad zu einer Bilddatei die als Projektbild im tibi-admin verwendet wird - imageUrl: https://testversion.online/demo.png - - # Liste möglicher Berechtigungen, die Benutzern zugeordnet werden können - permissions: - - # Name der Berechtigung - name: news - # Label für die Anzeige im Admin - # (kann string oder object mit Sprachen als keys sein) - label: - de: Neuigkeiten - en: News - - - name: pages - label: - de: Seiten - en: Pages - -# "collections" ist eine Auflistung von Kollektions-Konfigurationen. + # Pfad zu einer Bilddatei die als Projektbild im tibi-admin verwendet wird + imageUrl: https://testversion.online/demo.png + + # Liste möglicher Berechtigungen, die Benutzern zugeordnet werden können + permissions: + - # Name der Berechtigung + name: news + # Label für die Anzeige im Admin + # (kann string oder object mit Sprachen als keys sein) + label: + de: Neuigkeiten + en: News + + - name: pages + label: + de: Seiten + en: Pages + +# "collections" ist eine Auflistung von Kollektions-Konfigurationen. # Hier bietet sich eine Auslagerung und Einbindung via YAML-Tag "!include" an. collections: - - !include collections/democol.yml + - !include collections/democol.yml + - !include collections/medialib.yml # Unter "jobs" können Jobs definiert werden, die regelmäßig ausgeführt werden sollen. jobs: @@ -39,4 +40,4 @@ jobs: # Werden Dateien innerhalb vom tibi-admin benötigt, bietet es sich an diese über # "assets"-Pfade erreichbar zu machen. assets: - - !include assets/demoasset.yml + - !include assets/demoassets.yml diff --git a/api/hooks/democol/delete_delete.js b/api/hooks/democol/delete_delete.js new file mode 100644 index 0000000..e69de29 diff --git a/api/hooks/democol/delete_return.js b/api/hooks/democol/delete_return.js new file mode 100644 index 0000000..e69de29 diff --git a/api/hooks/democol/post_bind.js b/api/hooks/democol/post_bind.js new file mode 100644 index 0000000..e69de29 diff --git a/api/hooks/democol/post_create.js b/api/hooks/democol/post_create.js new file mode 100644 index 0000000..e69de29 diff --git a/api/hooks/democol/post_return.js b/api/hooks/democol/post_return.js new file mode 100644 index 0000000..e69de29 diff --git a/api/hooks/democol/post_validate.js b/api/hooks/democol/post_validate.js new file mode 100644 index 0000000..e69de29 diff --git a/api/hooks/democol/put_bind.js b/api/hooks/democol/put_bind.js new file mode 100644 index 0000000..e69de29 diff --git a/api/hooks/democol/put_return.js b/api/hooks/democol/put_return.js new file mode 100644 index 0000000..e69de29 diff --git a/api/hooks/democol/put_update.js b/api/hooks/democol/put_update.js new file mode 100644 index 0000000..e69de29 diff --git a/api/hooks/democol/put_validate.js b/api/hooks/democol/put_validate.js new file mode 100644 index 0000000..e69de29 diff --git a/docs/README.md b/docs/README.md index 32a04de..b7db39e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -16,6 +16,7 @@ - [fields](projektkonfig/collections/fields.md) - [Datentypen](projektkonfig/collections/fields/datentypen.md) - [Admin Widgets](projektkonfig/collections/fields/widgets.md) + - [· ContentBuilder](projektkonfig/collections/fields/widgets/contentbuilder.md) - [indexes](projektkonfig/collections/indexes.md) - [hooks](projektkonfig/collections/hooks.md) - [imageFilter](projektkonfig/collections/imageFilter.md) diff --git a/docs/projektkonfig/collections/dependsOn.webm b/docs/projektkonfig/collections/dependsOn.webm new file mode 100644 index 0000000..144b7da Binary files /dev/null and b/docs/projektkonfig/collections/dependsOn.webm differ diff --git a/docs/projektkonfig/collections/fields.md b/docs/projektkonfig/collections/fields.md index 7c53205..fd19b2a 100644 --- a/docs/projektkonfig/collections/fields.md +++ b/docs/projektkonfig/collections/fields.md @@ -10,6 +10,12 @@ Zunächst folgt der grundlegende Aufbau des Feld-Objektes: ## validator Objekt + + +Wie im Beispiel von **fields/date.yml** unter `validator` zu sehen ist, wird dort ein Datum nach dem aktuellen erwartet. Wie der Validator sich auf die UI auswirkt, ist im obigen Video zu sehen. + Das `validator` Objekt wird *tibi-server* seitig genutzt um die Daten zu validieren. Da das `validator` Objekt dem *tibi-admin* ebenso zur Verfügung steht, kann vorab eine client-seitige Validierung zusätzlich durchgeführt werden. Attribute des Objektes: @@ -43,6 +49,53 @@ Sollte der `eval` Code im *tibi-admin* nicht lauffähig sein (nicht abgefangene ## dependsOn + + +Obige Darstellung wie im Video wird beispielsweise durch folgende Feld-Konfiguration erreicht: + +```yaml +# in einer Kollektions-Konfiguration +fields: + - name: type + type: string + meta: + label: + de: Typ + en: Type + widget: select + choices: + - name: + de: Standardseite + en: Standard page + id: page + - name: + de: News + en: News + id: news + + - name: title + type: string + meta: + label: + de: Titel + en: Title + + - name: date + type: date + meta: + label: + de: Titel + en: title + widget: date + defaultValue: + eval: new Date() + dependsOn: + eval: $parent?.type == "news" + +``` + `meta.dependsOn` kann als Objekt mit `eval`-Attribut für Javascript oder als `string` mit dem Feldnamen (Punktschreibweise, z.B. `"additionalData.author"`) angegeben werden. Wird der Feldname verwendet wird nur geprüft, ob das Feld belegt ist. TODO @@ -60,6 +113,7 @@ Die Rückgabe des Javascript-Codes beeinflusst die Einblendung des betroffenen F | `true` | Das Feld wird angezeigt | | `false` | Das Feld wird ausgeblendet | + ## defaultValue Für die Vorlegung neu anzulegender Datensätze kann in `field.meta.defaultValue` direkt der Standardwert hinterlegt werden, oder über `field.meta.defaultValue.eval` ein Javascript-Code angegeben werden, der den Wert ermittelt. Die Rückgabe des Javascript-Codes, sowie auch die direkte Vergabe des Wertes muss dem Datentyp des Feldes entsprechen. diff --git a/docs/projektkonfig/collections/fields/widgets.md b/docs/projektkonfig/collections/fields/widgets.md index 40ec4ca..56161e8 100644 --- a/docs/projektkonfig/collections/fields/widgets.md +++ b/docs/projektkonfig/collections/fields/widgets.md @@ -34,4 +34,6 @@ Nicht jedes Widget kann mit jedem Datentyp umgehen, die möglichen Datentypen we ## tabs -## contentbuilder \ No newline at end of file +## contentbuilder + +siehe: [ContentBuilder](./widgets/contentbuilder.md) diff --git a/docs/projektkonfig/collections/fields/widgets/contentbuilder-module.webm b/docs/projektkonfig/collections/fields/widgets/contentbuilder-module.webm new file mode 100644 index 0000000..4963686 Binary files /dev/null and b/docs/projektkonfig/collections/fields/widgets/contentbuilder-module.webm differ diff --git a/docs/projektkonfig/collections/fields/widgets/contentbuilder.md b/docs/projektkonfig/collections/fields/widgets/contentbuilder.md new file mode 100644 index 0000000..f08cfe2 --- /dev/null +++ b/docs/projektkonfig/collections/fields/widgets/contentbuilder.md @@ -0,0 +1,31 @@ +# contentbuilder + +> Der ContentBuilder ist ein Drittanbieter-Produkt und steht nicht in jeder Lizenz zur Verfügung. Bitte kontaktieren Sie uns, wenn Sie Interesse an diesem Widget haben. + +Für die Gestaltung von HTML-Inhalten ist der ContentBuilder eine einfache und intuitive Lösung. Es sind Layout-Hilfmittel wie Spalten und Zeilen ebenso verfügbar, wie die Möglichkeit Dateien (Bilder, Video, Downloads) direkt in den HTML-Code einzubinden. + +Wie der ContentBuilder an einem Feld konfiguriert wird verdeutlicht folgendes Beispiel: + +!!!include(api/collections/fields/content.yml)!!! + +## Mediathek Kollektion + +Wie aus der obigen Definition unterhalb von z.B. "imageSelect" zu lesen, bedarf es einer eigenen Kollektion für Bilder und andere Dateien. Diese Kollektion könnte wie folgt aussehen: + +> Die Bedeutung der nicht beschriebenen Eigenschaften ist unter [collections](./../../../collections.md) beschrieben. + +!!!include(api/collections/medialib.yml)!!! + +## Module (customTags) + +Die Einbindung des konfigurierten Beispiel-Moduls aus obiger Definition erfolgt im ContentBuilder wie im folgenden Video zu sehen ist: + + + +Wie oben schon erwähnt, sind die `placeholder` frei wählbar. Eine HTML5-Schreibweise bietet sich aber sowohl für das Styling, als auch für die spätere Einbindung in ein Frontend an. + +In unserem Beispiel hier wurden zusättzlich zum eigentlichen Modul-Tag noch Attribute (`title` und `description`) definiert. Diese können dann im Frontend das eigentliche Modul beeinflussen. + +Im Frontend könnte ein Modul dann später als "Custom Element" implementiert werden oder es wird ein HTML-Parser verwendet, der die Tags durch eigene Komponenten ersetzt, wie er im Anhang [TODO] zu finden ist. \ No newline at end of file diff --git a/docs/projektkonfig/collections/validator.webm b/docs/projektkonfig/collections/validator.webm new file mode 100644 index 0000000..6a34e05 Binary files /dev/null and b/docs/projektkonfig/collections/validator.webm differ diff --git a/frontend/_dist_/empty b/frontend/_dist_/empty new file mode 100644 index 0000000..e69de29