markdown-it-code-include
This commit is contained in:
parent
6dc27dce41
commit
ac656bc5ef
8
docpress.json
Normal file
8
docpress.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"markdown": {
|
||||||
|
"plugins": {
|
||||||
|
"code-include": {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -6,220 +6,7 @@ Die Konfiguration einer Kollektion sollte zur besseren Übersicht innerhalb eine
|
|||||||
|
|
||||||
Eine solche Datei (z.B. democol.yml) hat folgenden Aufbau:
|
Eine solche Datei (z.B. democol.yml) hat folgenden Aufbau:
|
||||||
|
|
||||||
```yaml
|
!!!include(api/collections/democol.yml)!!!
|
||||||
# Der Name der Kollektion wird in der Rest-API-URL verwendet, z.B.
|
|
||||||
# /_/demo/democol
|
|
||||||
name: democol
|
|
||||||
|
|
||||||
# Standardsprache für Text-Index in der Datenbank
|
|
||||||
defaultLanguage: de
|
|
||||||
|
|
||||||
# Enthält die Kollektion Felder vom Typ "file", so werden die
|
|
||||||
# hochgeladenen Dateien unter dem Ordner abgelegt, der mit
|
|
||||||
# "uploadPath" bestimmt wird.
|
|
||||||
uploadPath: ../media/democol
|
|
||||||
|
|
||||||
# Wie auch in der Top-Level-Konfig "config.yml" ist auch hier ein
|
|
||||||
# "meta" Objekt möglich und nötig für die Konfiguration der
|
|
||||||
# Admin-UI.
|
|
||||||
# Mögliche Angaben werden im seperaten Kapitel behandelt.
|
|
||||||
meta: !include democol/meta.yml
|
|
||||||
|
|
||||||
# "imageFilter" definieren Filter, die Bilder bearbeiten, wie
|
|
||||||
# z.B. Verkleinerung.
|
|
||||||
# Mögliche Angaben werden im seperaten Kapitel behandelt.
|
|
||||||
imageFilter: !include democol/imageFilter.yml
|
|
||||||
|
|
||||||
# Projektionen der Daten werden via GET-Parameter "projection=..."
|
|
||||||
# referenziert.
|
|
||||||
# "projections" is ein Objekt, dass die Namen der Projektionen
|
|
||||||
# als Key führt.
|
|
||||||
projections:
|
|
||||||
# "list" = Name der Projektion
|
|
||||||
list:
|
|
||||||
# "select" definiert als Keys die Felder, die beim Abruf
|
|
||||||
# dieser Projektion in den Ausgabe-Daten enthalten sind.
|
|
||||||
# Felder werden über die Punkt-Notation referenziert.
|
|
||||||
select:
|
|
||||||
title: 1
|
|
||||||
date: 1
|
|
||||||
# refenziert das "subField" "author" unterhalb von "meta"
|
|
||||||
meta.author: 1
|
|
||||||
details:
|
|
||||||
# Alternativ kann "select" auch Auschlussregeln definieren.
|
|
||||||
# Eine Mischung von Inkludieren und Auschluss ist NICHT
|
|
||||||
# möglich.
|
|
||||||
select:
|
|
||||||
comment: 0
|
|
||||||
full:
|
|
||||||
# Ein leeres "select" Objekt beschränkt die Ausgabe der
|
|
||||||
# Daten nicht und ist Standard, wenn der "projection="
|
|
||||||
# Parameter nicht verwendet wurde.
|
|
||||||
select:
|
|
||||||
|
|
||||||
# Allgeine Zugriffsregeln auf Kollektions-Ebene werden mit dem
|
|
||||||
# "permissions" Objekt festgelegt.
|
|
||||||
permissions:
|
|
||||||
# Unter "public" werden die Zugriffsrechte für die Öffentlichkeit
|
|
||||||
# definiert.
|
|
||||||
public:
|
|
||||||
# "methods" führt die HTTP-Methoden auf, die erlaubt sind
|
|
||||||
methods:
|
|
||||||
# "get: true" bedeutet hier, dass jeder die Daten lesen darf
|
|
||||||
get: true
|
|
||||||
# "post", also Einträge erstellen, "put" = Bearbeiten und
|
|
||||||
# "delete" = löschen darf die Öffentlichkeit nicht.
|
|
||||||
post: false
|
|
||||||
put: false
|
|
||||||
delete: false
|
|
||||||
# Ist "validProjections" definiert, sind auch nur genau die
|
|
||||||
# aufgelisteten Projektionen erlaubt, welche zwingend mit dem
|
|
||||||
# GET-Parameter "projection=..." ausgewählt werden müssen.
|
|
||||||
validProjections:
|
|
||||||
- list
|
|
||||||
- details
|
|
||||||
|
|
||||||
# Der Key "user" steht für ALLE Benutzer die dem Projekt
|
|
||||||
# zugeordnet sind.
|
|
||||||
# D.h. eine feinere Abstufung auf Benutzerebene ist mit dem
|
|
||||||
# Key "user" allein nicht möglich.
|
|
||||||
# Für eine feinere Abstufung können nachgelagerte Hooks
|
|
||||||
# dienen oder die Verwendung von zugeordneten benutzerdefinierten
|
|
||||||
# "permissions" (siehe meta Objekt).
|
|
||||||
user:
|
|
||||||
methods:
|
|
||||||
get: true
|
|
||||||
post: false
|
|
||||||
put: false
|
|
||||||
delete: false
|
|
||||||
# Fehlt "validProjections", sind automatisch alle Projektionen
|
|
||||||
# erlaubt, wobei hier auch der GET-Parameter "projection="
|
|
||||||
# weggelassen werden darf und somit alle Felder in der Ausgabe
|
|
||||||
# zu finden sind.
|
|
||||||
|
|
||||||
# Folgende Brechtigung wird angewandt, wenn der Zugriff über
|
|
||||||
# den GET-Parameter "token=" oder die Header-Anweisung "token: "
|
|
||||||
# angefragt wird.
|
|
||||||
# "token" ist dabei die Markierung, dass es sich um einen Token
|
|
||||||
# handelt und "${TOKEN}" ist der benutzerdefinierte Token selbst.
|
|
||||||
# Dieser wird hier über eine Umgebungsvariable "TOKEN" injiziert,
|
|
||||||
# die in "config.yml.env" definiert werden kann mit "TOKEN=...".
|
|
||||||
token:${TOKEN}:
|
|
||||||
methods:
|
|
||||||
get: true
|
|
||||||
post: true
|
|
||||||
put: true
|
|
||||||
delete: true
|
|
||||||
|
|
||||||
# Alle Berechtigungs-Namen, die nicht "public", "user" oder "token:..."
|
|
||||||
# heißen, sind benutzerdefinierte Berechtigungen, die Benutzern
|
|
||||||
# zugeordnet werden können.
|
|
||||||
# Eine mögliche Auflistung um Vorschläge in der Admin-UI anzubieten,
|
|
||||||
# werden im Top-Level meta-Objekt der "config.yml" unter "permissions"
|
|
||||||
# definiert.
|
|
||||||
pages:
|
|
||||||
methods:
|
|
||||||
get: true
|
|
||||||
post: true
|
|
||||||
put: true
|
|
||||||
delete: true
|
|
||||||
|
|
||||||
# "hooks" definieren die Algorithmen, die Daten und Abläufe zu bestimmten
|
|
||||||
# HTTP-Methoden und Schritten der API manipulieren können.
|
|
||||||
hooks:
|
|
||||||
# Hooks für die Methode "get"
|
|
||||||
get:
|
|
||||||
# "read"-Schritt wird ausgeführt, bevor die Daten von der Datenbank
|
|
||||||
# gelesen werden.
|
|
||||||
read:
|
|
||||||
# "type" ist derzeit immer "javascript"
|
|
||||||
type: javascript
|
|
||||||
# "file" zeigt auf die Datei mit dem Javascript-Code relativ zum
|
|
||||||
# Ordner der "config.yml" Datei.
|
|
||||||
file: hooks/democol/get_read.js
|
|
||||||
# "return"-Schritt wird ausgeführt, bevor die gelesenen Daten über
|
|
||||||
# HTTP übertragen werden.
|
|
||||||
return:
|
|
||||||
type: javascript
|
|
||||||
file: hooks/democol/get_return.js
|
|
||||||
|
|
||||||
# Hooks für die Methode "post"
|
|
||||||
post:
|
|
||||||
# "bind" wird ausgeführt, bevor die übertragenen Daten in eine
|
|
||||||
# Objekt-Struktur umgewandelt werden.
|
|
||||||
# Der tibi-server erwarten nach diesem Schritt gültige JSON-Daten,
|
|
||||||
# d.h. sollte es möglich gemacht werden, dass andere Daten übertragen
|
|
||||||
# werden, sind diese in diesem Hook abzufangen und zu verarbeiten.
|
|
||||||
bind:
|
|
||||||
type: javascript
|
|
||||||
file: hooks/democol/post_bind.js
|
|
||||||
# "validate" wird ausgeführt, bevor die Daten validiert werden.
|
|
||||||
validate:
|
|
||||||
type: javascript
|
|
||||||
file: hooks/democol/post_validate.js
|
|
||||||
# "create" wird ausgeführt, bevor das Objekt/Dokument in der Datenbank
|
|
||||||
# angelegt wird.
|
|
||||||
create:
|
|
||||||
type: javascript
|
|
||||||
file: hooks/democol/post_create.js
|
|
||||||
# "return" wird ausgeführt, bevor die Serverantwort über HTTP
|
|
||||||
# übertragen wird.
|
|
||||||
return:
|
|
||||||
type: javascript
|
|
||||||
file: hooks/democol/post_return.js
|
|
||||||
|
|
||||||
# Hooks für die Methode "put"
|
|
||||||
put:
|
|
||||||
bind:
|
|
||||||
type: javascript
|
|
||||||
file: hooks/democol/put_bind.js
|
|
||||||
validate:
|
|
||||||
type: javascript
|
|
||||||
file: hooks/democol/put_validate.js
|
|
||||||
# "bind" und "validate" habe die gleiche Bedeutung wie Hooks der
|
|
||||||
# Methode "post".
|
|
||||||
# "update" wird ausgeführt bevor das Objekt in der Datenbank
|
|
||||||
# aktualisiert wird.
|
|
||||||
update:
|
|
||||||
type: javascript
|
|
||||||
file: hooks/democol/put_create.js
|
|
||||||
# "return" wird auch hier vor der Serverantwort ausgeführt.
|
|
||||||
return:
|
|
||||||
type: javascript
|
|
||||||
file: hooks/democol/put_return.js
|
|
||||||
|
|
||||||
# Hooks für die Methode "delete"
|
|
||||||
delete:
|
|
||||||
# Der "delete"-Hook wird vor dem eigentlichen Löschen ausgeführt
|
|
||||||
delete:
|
|
||||||
type: javascript
|
|
||||||
file: hooks/democol/delete_delete.js
|
|
||||||
# "return"-Hook kann ebenso hier die Serverantwort manipulieren
|
|
||||||
return:
|
|
||||||
type: javascript
|
|
||||||
file: hooks/democol/delete_return.js
|
|
||||||
|
|
||||||
# "fields" stellen die Eigentliche Struktur der Kollektion dar.
|
|
||||||
# "fields" ist als Array angelegt um eine Standard-Sortierung
|
|
||||||
# in der Admin-UI vorzugeben.
|
|
||||||
fields:
|
|
||||||
# Das Einbinden von Feldern über extra Dateien bietet sich nur
|
|
||||||
# an, wenn das jeweilige Feld mehrfach von dieser oder anderen
|
|
||||||
# Kollektionen verwendet wird.
|
|
||||||
# Auf die möglichen Definitionen wird im Kapitel "fields"
|
|
||||||
# eingegangen.
|
|
||||||
- !include fields/title.yml
|
|
||||||
- !include fields/date.yml
|
|
||||||
- !include fields/type.yml
|
|
||||||
|
|
||||||
# Neben der Definition der Indexe innerhalbd des Feld-Objektes selbst,
|
|
||||||
# ist die Index-Definition global für die Kollektion auch hier möglich.
|
|
||||||
# Diese Definition ist z.B. für zusammengesetzte Index-Typen notwendig.
|
|
||||||
# Außerdem sind hier feinere Einstellungen für den Index möglich.
|
|
||||||
# Mehr dazu im "indexes" Kapitel
|
|
||||||
indexes:
|
|
||||||
- !include democol/textindex.yml
|
|
||||||
```
|
|
||||||
|
|
||||||
## imageFilter Objekt
|
## imageFilter Objekt
|
||||||
|
|
||||||
@ -230,34 +17,7 @@ Der Prozess selbst erfolgt beim ersten Abruf des Bildes und wird zwischengespeic
|
|||||||
|
|
||||||
Eine beispielhafte Konfiguration, die die Bilder nur verkleinert sieht so aus:
|
Eine beispielhafte Konfiguration, die die Bilder nur verkleinert sieht so aus:
|
||||||
|
|
||||||
```yaml
|
!!!include(api/collections/democol/imageFilter.yml)!!!
|
||||||
# Der Key des Objektes definiert den Namen des Filters.
|
|
||||||
# Jeder Filter ist eine Liste von Bildmanipulationen, die
|
|
||||||
# nacheinander angewandt werden.
|
|
||||||
# Die manipulierten Bilder werden gecachet. Ein nachträgliches
|
|
||||||
# Anpassen der Filter erfordert also das Löschen der gecachten
|
|
||||||
# Dateien welche sich jeweils neben den original Bilddateien
|
|
||||||
# im "uploadPath" der Kollektion befinden.
|
|
||||||
s:
|
|
||||||
- fit: true
|
|
||||||
height: 300
|
|
||||||
width: 300
|
|
||||||
resampling: lanczos
|
|
||||||
quality: 60
|
|
||||||
m:
|
|
||||||
- fit: true
|
|
||||||
height: 600
|
|
||||||
width: 600
|
|
||||||
resampling: lanczos
|
|
||||||
quality: 60
|
|
||||||
l:
|
|
||||||
- fit: true
|
|
||||||
height: 1200
|
|
||||||
width: 1200
|
|
||||||
resampling: lanczos
|
|
||||||
quality: 60
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
Folgende Attribute können Filter-Eintrage haben, wobei "fit" und "fill" exklusiv sind:
|
Folgende Attribute können Filter-Eintrage haben, wobei "fit" und "fill" exklusiv sind:
|
||||||
|
|
||||||
@ -289,86 +49,7 @@ Wie bereits an anderer Stelle beschrieben, dient das meta-Objekt zur Definition
|
|||||||
|
|
||||||
Folgende Angaben sind möglich:
|
Folgende Angaben sind möglich:
|
||||||
|
|
||||||
```yaml
|
!!!include(api/collections/democol/meta.yml)!!!
|
||||||
# Ein Label für die Admin-UI wird mehrsprachig folgendermaßen definiert
|
|
||||||
label:
|
|
||||||
de: Demo-Kolletion
|
|
||||||
en: Demo-Collection
|
|
||||||
|
|
||||||
# Jede Kolletion kann ein eigenes Icon aus mdijs bekommen.
|
|
||||||
muiIcon: web
|
|
||||||
|
|
||||||
# Die Standardsortierung bei ersten Aufruf der Kollektion.
|
|
||||||
defaultSort:
|
|
||||||
# Nach welchem Feld soll sortiert werden?
|
|
||||||
field: updatedTime
|
|
||||||
# ASC für aufsteigend oder DESC für absteigend
|
|
||||||
order: DESC
|
|
||||||
|
|
||||||
# Ist ein Javascript Message-Object-Empfänger implementiert, der empfangene
|
|
||||||
# Daten als Vorschau rendern kann, so ist dieser hier zu definieren.
|
|
||||||
# Implementierungshinweise zu einem Solchen gibt es später.
|
|
||||||
previewUrl: https://demo.testversion.online/preview
|
|
||||||
|
|
||||||
# Aus den definierten "imageFilter"-Angaben kann ein Filter für die
|
|
||||||
# Ausgabe der Thunbnails in der Admin-Ansicht ausgewählt werden.
|
|
||||||
defaultImageFilter: s
|
|
||||||
|
|
||||||
# Jede Kollektion kann über media-Querys mit mehreren Ansichten veknüpft werden.
|
|
||||||
# Mögliche Ansichten und die dazugehörigen CSS-Queries sind hier zu defineren.
|
|
||||||
views:
|
|
||||||
# Natürlich können die Angaben auch ausgelagert und mehrfach verwendet werden.
|
|
||||||
# Die möglichen Angaben werden im Kapitel "views" gezeigt.
|
|
||||||
- !include simpleList.yml
|
|
||||||
- !include table.yml
|
|
||||||
|
|
||||||
# Wird eine Kollektion als eine Gesamtliste schnell unübersichtlich, hild die
|
|
||||||
# Definition von "subNavigation".
|
|
||||||
# Die meisten Angaben sind aus obiger Beschreibung den meta-Objektes bekannt.
|
|
||||||
# Es wird hier nur auf die zusätzlichen Angaben eingegangen.
|
|
||||||
subNavigation:
|
|
||||||
- # Jede Unternavigation braucht einen eindeutigen Namen um diese später
|
|
||||||
# in z.B. Javascript-Code wieder erkennen zu können.
|
|
||||||
name: pages
|
|
||||||
label:
|
|
||||||
de: Seiten
|
|
||||||
en: Pages
|
|
||||||
muiIcon: page-layout-body
|
|
||||||
defaultSort:
|
|
||||||
field: titel
|
|
||||||
order: ASC
|
|
||||||
views:
|
|
||||||
- !include simpleList.yml
|
|
||||||
- !include table.yml
|
|
||||||
# Um mehr Übersicht zu bekommen können zum Einen andere "views" und "defaultSort"
|
|
||||||
# genutzt werden. Es kann aber auch eine Einschränkung der Daten über eine
|
|
||||||
# Vorfilterung via "filter" geben. "filter" ist ein Objekt mit MongoDB-Filterangaben.
|
|
||||||
# siehe: https://www.mongodb.com/docs/compass/current/query/filter/
|
|
||||||
filter:
|
|
||||||
type: page
|
|
||||||
|
|
||||||
- name: news
|
|
||||||
label:
|
|
||||||
de: Neuigkeiten
|
|
||||||
en: News
|
|
||||||
muiIcon: newspaper
|
|
||||||
defaultSort:
|
|
||||||
field: date
|
|
||||||
order: DESC
|
|
||||||
views:
|
|
||||||
- !include simpleList.yml
|
|
||||||
- !include table.yml
|
|
||||||
filter:
|
|
||||||
type: news
|
|
||||||
|
|
||||||
# Standardmäßig werden im Formular zu Eingabe der Daten alle Felder von "fields"
|
|
||||||
# untereinander angeordnet.
|
|
||||||
# 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
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
### views Liste
|
### views Liste
|
||||||
|
|
||||||
@ -380,91 +61,14 @@ Folgende Views gibt es derzeit:
|
|||||||
|
|
||||||
#### simpleList
|
#### simpleList
|
||||||
|
|
||||||
```yaml
|
!!!include(api/collections/democol/simpleList.yml)!!!
|
||||||
# "type" legt den Typ des Views fest.
|
|
||||||
type: simpleList
|
|
||||||
# Die Auswahl erfolgt über folgende "mediaQuery".
|
|
||||||
# (hier also bis maximal 599px Fensterbreite)
|
|
||||||
mediaQuery: "(max-width:599px)"
|
|
||||||
|
|
||||||
# 3 Blöcke können in der simpleList verwendet werden.
|
|
||||||
# Haupttext "primaryText" und optional 2 weitere Angaben über
|
|
||||||
# "secondaryText" und "tertiaryText".
|
|
||||||
# Die Angabe des jeweiligen Feldes erfolgt als String oder
|
|
||||||
# Objekt mit der "source"-Eigenschaft.
|
|
||||||
# Das Feld selbst wird in Punkt-Notation angegeben.
|
|
||||||
# Die Darstellung selbst ist abhängig von der Feld-Konfiguration
|
|
||||||
# selbst, die unter fields in der Kollektions-Konfiguration
|
|
||||||
# stattfindet.
|
|
||||||
primaryText: title
|
|
||||||
secondaryText:
|
|
||||||
source: date
|
|
||||||
tertiaryText: meta.author
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
#### table
|
#### table
|
||||||
|
|
||||||
```yaml
|
!!!include(api/collections/democol/table.yml)!!!
|
||||||
type: table
|
|
||||||
# Dieser View wird ab einer Fensterbreite von 600px angezeigt.
|
|
||||||
mediaQuery: "(min-width:600px)"
|
|
||||||
# Da es sich um eine Tabelle handelt, benötigt es eine Auflistung
|
|
||||||
# der Spalten unter "columns
|
|
||||||
columns:
|
|
||||||
# Jede Spalte zeigt auf ein Feld.
|
|
||||||
# Entweder wird hier nur der String des Feldes in Punk-Notation
|
|
||||||
# angegeben oder ein Objekt mit weiteren Möglichkeiten
|
|
||||||
- # "source" definiert das Feld via Punkt-Notation.
|
|
||||||
source: updateTime
|
|
||||||
# Mit "label" kann das Label aus der Feld-Konfiguration
|
|
||||||
# überschrieben werden.
|
|
||||||
label:
|
|
||||||
de: letztes Update
|
|
||||||
en: last update
|
|
||||||
# Ebenso kann der "type" der Feldkonfiguration überschrieben
|
|
||||||
# werden oder gesetzt werden, wie in diesem Fall, da "updateTime"
|
|
||||||
# ein Standardfeld der Kollektion ist und nicht in der "fields"-Liste
|
|
||||||
# konfiguriert wird.
|
|
||||||
type: date
|
|
||||||
- source: title
|
|
||||||
# Mit "filter: true" wird festegelegt, dass über diese Spalte
|
|
||||||
# die Daten filterbar sind.
|
|
||||||
filter: true
|
|
||||||
- source: date
|
|
||||||
filter: true
|
|
||||||
- source: type
|
|
||||||
filter: true
|
|
||||||
```
|
|
||||||
|
|
||||||
### tablist
|
### tablist
|
||||||
|
|
||||||
Wird die "tablist" verwendet, ist sicher zu stellen, dass alle Felder in der Definition aufgenommen werden. Werden Felder nicht in die "tablist" aufgenommen, sind diese weiterhin in einer Gesamtliste unterhalb der Tabs und bringen das Layout durcheinander.
|
Wird die "tablist" verwendet, ist sicher zu stellen, dass alle Felder in der Definition aufgenommen werden. Werden Felder nicht in die "tablist" aufgenommen, sind diese weiterhin in einer Gesamtliste unterhalb der Tabs und bringen das Layout durcheinander.
|
||||||
|
|
||||||
```yaml
|
!!!include(api/collections/democol/tablist.yml)!!!
|
||||||
# Hier wird der initial zu öffnende Tab festgelegt.
|
|
||||||
# Ist dieser nicht festgelegt, wird automatisch der erste Tab
|
|
||||||
# aus der "tabs" Liste gewaählt.
|
|
||||||
activeTab: general
|
|
||||||
# "tabs" ist die eigentliche Liste
|
|
||||||
tabs:
|
|
||||||
- # Jeder Tab braucht einen Namen, über den er refereziert
|
|
||||||
# werden kann.
|
|
||||||
name: general
|
|
||||||
# Die übliche Labelangabe kann auch hier mehrpsrachig erfolgen.
|
|
||||||
label:
|
|
||||||
de: Allgemein
|
|
||||||
en: General
|
|
||||||
# Welche Felder dieser Tab anzeigen soll, wird über "subFields"
|
|
||||||
# beschrieben.
|
|
||||||
subFields:
|
|
||||||
- source: title
|
|
||||||
- source: date
|
|
||||||
- name: meta
|
|
||||||
label:
|
|
||||||
de: Metaangaben
|
|
||||||
en: Meta data
|
|
||||||
subFields:
|
|
||||||
- source: meta.author
|
|
||||||
|
|
||||||
```
|
|
||||||
|
@ -6,47 +6,4 @@ Es hat sich jedoch als günstig erwiesen bei Webprojekten die Datei und alle and
|
|||||||
|
|
||||||
## Aufbau
|
## Aufbau
|
||||||
|
|
||||||
```yaml
|
!!!include(api/config.yml)!!!
|
||||||
# Der Namespace legt die eigentliche Projektbezeichnung und
|
|
||||||
# den Datenbankkontext fest.
|
|
||||||
# Er sollte nach Projektinitialisierung auf dem tibi-server
|
|
||||||
# nicht mehr angepasst werden.
|
|
||||||
# In den Projekteinstellungen im tibi-server kann der Namespace
|
|
||||||
# durch einen Datenbankeintrag überschrieben werden.
|
|
||||||
# Über die Bezeichnung des Namespace plus einen Prefix der in
|
|
||||||
# der globalen Server-Konfig hinterlegt ist, definiert sich der
|
|
||||||
# Datenbank-Name innerhalb der MongoDB.
|
|
||||||
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 in der Admin-UI
|
|
||||||
# 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 Einbidnung via
|
|
||||||
# YAML-Tag "!include" an.
|
|
||||||
collections:
|
|
||||||
- !include collections/democol.yml
|
|
||||||
```
|
|
@ -6,66 +6,7 @@ Es gibt grundlegende Angaben, die jedes Feld haben muss um vom tibi-server akzep
|
|||||||
|
|
||||||
Zunächst folgt der grundlegende Aufbau des Feld-Objektes:
|
Zunächst folgt der grundlegende Aufbau des Feld-Objektes:
|
||||||
|
|
||||||
```yaml
|
!!!include(api/collections/fields/date.yml)!!!
|
||||||
# Der Name des Feldes wird in der Datenbank zum Objekt ebenso
|
|
||||||
# wie in der Ein- und Ausgabe über die API verwendet.
|
|
||||||
name: date
|
|
||||||
|
|
||||||
# Über "type" wird der Datentyp in der Datenbank festgelegt.
|
|
||||||
# Mögliche Typen sind weiter unten aufgelistet.
|
|
||||||
type: date
|
|
||||||
|
|
||||||
# Direkt am Feld kann eine Index-Definition erfolgen.
|
|
||||||
# Folgende mögliche Werte können ihn die Liste aufgenommen werden:
|
|
||||||
# "single" - Standard-Index für diese Feld
|
|
||||||
# "unique" - Das Feld muss einen eindeutigen Wert haben
|
|
||||||
# "text" - Alle "text"-Indexanganben aller Felder werden zu einem
|
|
||||||
# gemeinsamen Volltext-Index kombiniert
|
|
||||||
#
|
|
||||||
# Die Angabe des Volltextindex ist besser unter "collections.X.indexes"
|
|
||||||
# vorzunehmen.
|
|
||||||
index:
|
|
||||||
- single
|
|
||||||
|
|
||||||
# Jede Datenübertragung an des Server wird validiert, d.h. es werden
|
|
||||||
# keine Datentypen angenommen, die nicht zu "type" passen.
|
|
||||||
# Darüber hinaus kann via "validator" eine zusätzliche Validierung
|
|
||||||
# vorgenommen werden.
|
|
||||||
# Dazu gibt es ein extra Kapitel.
|
|
||||||
validator:
|
|
||||||
required: true
|
|
||||||
eval: new Date($this) > new Date()
|
|
||||||
|
|
||||||
# Und natürlich gibt es auch hier ein "meta" Objekt zur Steuerung
|
|
||||||
# der Admin-UI.
|
|
||||||
meta:
|
|
||||||
# Das "label" des Feldes wird als Label vor dem Widget verwendet.
|
|
||||||
label:
|
|
||||||
de: Titel
|
|
||||||
en: title
|
|
||||||
|
|
||||||
# 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
|
|
||||||
|
|
||||||
# Standardwerte für neue Enträge können entweder direkt angegeben
|
|
||||||
# werden oder via Javascript client-seitig generiert werden.
|
|
||||||
# In den Kontext injizierte Variablen werden später beschrieben.
|
|
||||||
defaultValue:
|
|
||||||
# Das Ergebnis von "eval" wird hier als Standardwert verwendet.
|
|
||||||
# (hier das aktuelle Datum)
|
|
||||||
eval: new Date()
|
|
||||||
|
|
||||||
# Sollen Felder abhängig von bestimmten Bedingungen ein- oder
|
|
||||||
# ausgeblendet werden, geschieht das über Anweisungen in "dependsOn".
|
|
||||||
dependsOn:
|
|
||||||
# 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"
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
## validator Objekt
|
## validator Objekt
|
||||||
|
|
||||||
|
106
markdown-it-code-include/index.js
Normal file
106
markdown-it-code-include/index.js
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
const INCLUDE_RE = /!{3}\s*include(.+?)!{3}/i;
|
||||||
|
const BRACES_RE = /\((.+?)\)/i;
|
||||||
|
|
||||||
|
const include_plugin = (md, options) => {
|
||||||
|
const defaultOptions = {
|
||||||
|
root: '.',
|
||||||
|
getRootDir: (pluginOptions/*, state, startLine, endLine*/) => pluginOptions.root,
|
||||||
|
includeRe: INCLUDE_RE,
|
||||||
|
throwError: false,
|
||||||
|
bracesAreOptional: false,
|
||||||
|
notFoundMessage: 'File \'{{FILE}}\' not found.',
|
||||||
|
circularMessage: 'Circular reference between \'{{FILE}}\' and \'{{PARENT}}\'.'
|
||||||
|
};
|
||||||
|
|
||||||
|
if (typeof options === 'string') {
|
||||||
|
options = {
|
||||||
|
...defaultOptions,
|
||||||
|
root: options
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
options = {
|
||||||
|
...defaultOptions,
|
||||||
|
...options
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const _replaceIncludeByContent = (src, rootdir, parentFilePath, filesProcessed) => {
|
||||||
|
filesProcessed = filesProcessed ? filesProcessed.slice() : []; // making a copy
|
||||||
|
let cap, filePath, mdSrc, errorMessage;
|
||||||
|
|
||||||
|
// store parent file path to check circular references
|
||||||
|
if (parentFilePath) {
|
||||||
|
filesProcessed.push(parentFilePath);
|
||||||
|
}
|
||||||
|
while ((cap = options.includeRe.exec(src))) {
|
||||||
|
let includePath = cap[1].trim();
|
||||||
|
const sansBracesMatch = BRACES_RE.exec(includePath);
|
||||||
|
|
||||||
|
if (!sansBracesMatch && !options.bracesAreOptional) {
|
||||||
|
errorMessage = `INCLUDE statement '${src.trim()}' MUST have '()' braces around the include path ('${includePath}')`;
|
||||||
|
} else if (sansBracesMatch) {
|
||||||
|
includePath = sansBracesMatch[1].trim();
|
||||||
|
} else if (!/^\s/.test(cap[1])) {
|
||||||
|
// path SHOULD have been preceeded by at least ONE whitespace character!
|
||||||
|
/* eslint max-len: "off" */
|
||||||
|
errorMessage = `INCLUDE statement '${src.trim()}': when not using braces around the path ('${includePath}'), it MUST be preceeded by at least one whitespace character to separate the include keyword and the include path.`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!errorMessage) {
|
||||||
|
filePath = path.resolve(rootdir, includePath);
|
||||||
|
|
||||||
|
// check if child file exists or if there is a circular reference
|
||||||
|
if (!fs.existsSync(filePath)) {
|
||||||
|
// child file does not exist
|
||||||
|
errorMessage = options.notFoundMessage.replace('{{FILE}}', filePath);
|
||||||
|
} else if (filesProcessed.indexOf(filePath) !== -1) {
|
||||||
|
// reference would be circular
|
||||||
|
errorMessage = options.circularMessage.replace('{{FILE}}', filePath).replace('{{PARENT}}', parentFilePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if there were any errors
|
||||||
|
if (errorMessage) {
|
||||||
|
if (options.throwError) {
|
||||||
|
throw new Error(errorMessage);
|
||||||
|
}
|
||||||
|
mdSrc = `\n\n# INCLUDE ERROR: ${errorMessage}\n\n`;
|
||||||
|
} else {
|
||||||
|
// get content of child file
|
||||||
|
mdSrc = fs.readFileSync(filePath, 'utf8');
|
||||||
|
// check if child file also has includes
|
||||||
|
mdSrc = _replaceIncludeByContent(mdSrc, path.dirname(filePath), filePath, filesProcessed);
|
||||||
|
// remove one trailing newline, if it exists: that way, the included content does NOT
|
||||||
|
// automatically terminate the paragraph it is in due to the writer of the included
|
||||||
|
// part having terminated the content with a newline.
|
||||||
|
// However, when that snippet writer terminated with TWO (or more) newlines, these, minus one,
|
||||||
|
// will be merged with the newline after the #include statement, resulting in a 2-NL paragraph
|
||||||
|
// termination.
|
||||||
|
const len = mdSrc.length;
|
||||||
|
if (mdSrc[len - 1] === '\n') {
|
||||||
|
mdSrc = mdSrc.substring(0, len - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const labelStyle = `padding: 0 4px; font-size: 12px; font-weight: bold; color: #ffffff; background: #444444; opacity: .6;`
|
||||||
|
|
||||||
|
const fileLabel = `<div style="position:relative; height: 0px;"><div style="position:absolute; top: -10px;${labelStyle}">${includePath}</div></div>\n\n`
|
||||||
|
const fileExt = includePath.replace(/^.+\./, "")
|
||||||
|
|
||||||
|
// replace include by file content
|
||||||
|
src = src.slice(0, cap.index) + fileLabel + "```" + fileExt + "\n" + mdSrc + "\n```" + src.slice(cap.index + cap[0].length, src.length);
|
||||||
|
}
|
||||||
|
return src;
|
||||||
|
};
|
||||||
|
|
||||||
|
const _includeFileParts = (state, startLine, endLine/*, silent*/) => {
|
||||||
|
state.src = _replaceIncludeByContent(state.src, options.getRootDir(options, state, startLine, endLine));
|
||||||
|
};
|
||||||
|
|
||||||
|
md.core.ruler.before('normalize', 'include', _includeFileParts);
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = include_plugin;
|
24
markdown-it-code-include/package.json
Normal file
24
markdown-it-code-include/package.json
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"name": "markdown-it-code-include",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"description": "A markdown-it plugin to include code blocks.",
|
||||||
|
"main": "./index.js",
|
||||||
|
"scripts": {
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"markdown",
|
||||||
|
"markdown-it",
|
||||||
|
"markdown-it-plugin",
|
||||||
|
"code-blocks",
|
||||||
|
"fence"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"node-html-parser": "^1.3.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"markdown-it": "^12.0.0",
|
||||||
|
"markdown-it-testgen": "^0.1.6",
|
||||||
|
"path": "^0.12.7"
|
||||||
|
}
|
||||||
|
}
|
@ -10,6 +10,9 @@
|
|||||||
"docpress": "^0.8.2",
|
"docpress": "^0.8.2",
|
||||||
"tibi-types": "https://gitbase.de/cms/tibi-types.git#commit=c795339d1c7c91266cafd8b5914a57972565939a"
|
"tibi-types": "https://gitbase.de/cms/tibi-types.git#commit=c795339d1c7c91266cafd8b5914a57972565939a"
|
||||||
},
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"markdown-it-code-include": "./markdown-it-code-include"
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"serve": "docpress serve",
|
"serve": "docpress serve",
|
||||||
"build": "docpress build"
|
"build": "docpress build"
|
||||||
|
28
yarn.lock
28
yarn.lock
@ -2860,6 +2860,15 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"he@npm:1.2.0":
|
||||||
|
version: 1.2.0
|
||||||
|
resolution: "he@npm:1.2.0"
|
||||||
|
bin:
|
||||||
|
he: bin/he
|
||||||
|
checksum: 3d4d6babccccd79c5c5a3f929a68af33360d6445587d628087f39a965079d84f18ce9c3d3f917ee1e3978916fc833bb8b29377c3b403f919426f91bc6965e7a7
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"highlight.js@npm:^9.13.1":
|
"highlight.js@npm:^9.13.1":
|
||||||
version: 9.18.5
|
version: 9.18.5
|
||||||
resolution: "highlight.js@npm:9.18.5"
|
resolution: "highlight.js@npm:9.18.5"
|
||||||
@ -3975,6 +3984,15 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"markdown-it-code-include@file:./markdown-it-code-include::locator=tibi-docs%40workspace%3A.":
|
||||||
|
version: 0.0.0
|
||||||
|
resolution: "markdown-it-code-include@file:./markdown-it-code-include#./markdown-it-code-include::hash=2566cb&locator=tibi-docs%40workspace%3A."
|
||||||
|
dependencies:
|
||||||
|
node-html-parser: ^1.3.1
|
||||||
|
checksum: 68498c6dbba616c7f8df9affb0b39feccadea8fc8f5b74b3154697c8894afc4fe58e10ae2e37ff8707e9535d3c46212b1f2aab871e2a14406c6db44de5216a14
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"markdown-it-decorate@npm:1.2.2":
|
"markdown-it-decorate@npm:1.2.2":
|
||||||
version: 1.2.2
|
version: 1.2.2
|
||||||
resolution: "markdown-it-decorate@npm:1.2.2"
|
resolution: "markdown-it-decorate@npm:1.2.2"
|
||||||
@ -4476,6 +4494,15 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"node-html-parser@npm:^1.3.1":
|
||||||
|
version: 1.4.9
|
||||||
|
resolution: "node-html-parser@npm:1.4.9"
|
||||||
|
dependencies:
|
||||||
|
he: 1.2.0
|
||||||
|
checksum: fbcf5ea22f266b36a4761d448d3db7bcee6d7570e3a8ec38cbde223fe3d705cda1df8c287907520ae2d6bac8f68ef4dacdb5fd76c375c13c50bc746e980f4a91
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"nopt@npm:^6.0.0":
|
"nopt@npm:^6.0.0":
|
||||||
version: 6.0.0
|
version: 6.0.0
|
||||||
resolution: "nopt@npm:6.0.0"
|
resolution: "nopt@npm:6.0.0"
|
||||||
@ -6439,6 +6466,7 @@ __metadata:
|
|||||||
resolution: "tibi-docs@workspace:."
|
resolution: "tibi-docs@workspace:."
|
||||||
dependencies:
|
dependencies:
|
||||||
docpress: ^0.8.2
|
docpress: ^0.8.2
|
||||||
|
markdown-it-code-include: ./markdown-it-code-include
|
||||||
tibi-types: "https://gitbase.de/cms/tibi-types.git#commit=c795339d1c7c91266cafd8b5914a57972565939a"
|
tibi-types: "https://gitbase.de/cms/tibi-types.git#commit=c795339d1c7c91266cafd8b5914a57972565939a"
|
||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
Loading…
Reference in New Issue
Block a user