Explorar o código

feat: add options for branch, local_backend, and publish_mode (editorial flow)

Example for a YAML config:

```
  cms:
    branch: main
    local_backend: true
    publish_mode:
 ```

Close #2124
George Cushen %!s(int64=4) %!d(string=hai) anos
pai
achega
e470c4e2cf

+ 3 - 7
test/config.yaml

@@ -2,6 +2,7 @@ title: Wowchemy Test
 baseurl:
 module:
   imports:
+    - path: github.com/wowchemy/wowchemy-hugo-modules/wowchemy-cms
     - path: github.com/wowchemy/wowchemy-hugo-modules/wowchemy
 outputs:
   home: [HTML, RSS, JSON, WebAppManifest, headers, redirects]
@@ -14,11 +15,6 @@ params:
   font: native
   main_menu:
     enable: false
-  search:
-    engine: 0
-  security:
-    csp:
-      policy:
-      report_only: false
   cms:
-    branch: master
+    local_backend: true
+    publish_mode:

+ 7 - 0
test/content/admin/index.md

@@ -0,0 +1,7 @@
+---
+# Generate Wowchemy CMS
+type: wowchemycms
+outputs:
+  - wowchemycms_config
+  - HTML
+---

+ 1 - 0
test/content/home/section.md

@@ -1,5 +1,6 @@
 ---
 widget: blank
+widget_id: hello
 headless: true
 weight: 1
 design:

+ 5 - 1
test/go.mod

@@ -2,6 +2,10 @@ module github.com/wowchemy/wowchemy-hugo-modules/test
 
 go 1.15
 
-require github.com/wowchemy/wowchemy-hugo-modules/wowchemy master
+require (
+	github.com/wowchemy/wowchemy-hugo-modules/wowchemy main
+	github.com/wowchemy/wowchemy-hugo-modules/wowchemy-cms main
+)
 
 replace github.com/wowchemy/wowchemy-hugo-modules/wowchemy => ../wowchemy
+replace github.com/wowchemy/wowchemy-hugo-modules/wowchemy-cms => ../wowchemy-cms

+ 15 - 0
test/package.json

@@ -0,0 +1,15 @@
+{
+  "name": "wowchemy-test",
+  "version": "0.0.1",
+  "description": "Wowchemy Test Build",
+  "main": "",
+  "repository": "https://github.com/wowchemy/wowchemy-hugo-modules",
+  "author": "George Cushen",
+  "license": "MIT",
+  "private": true,
+  "scripts": {
+    "view": "hugo server --port 8080 --bind 0.0.0.0",
+    "build": "hugo --minify --cleanDestinationDir --gc --templateMetrics --templateMetricsHints",
+    "cms": "(trap 'kill 0' SIGINT; npx netlify-cms-proxy-server & hugo server --port 8080 --bind 0.0.0.0)"
+  }
+}

+ 0 - 1
test/view.sh

@@ -1 +0,0 @@
-hugo server -p 1330 --minify --templateMetrics --templateMetricsHints

+ 11 - 9
wowchemy-cms/README.md

@@ -6,16 +6,16 @@ Built upon the open source [Netlify CMS](https://www.netlifycms.org/) and [Netli
 
 ## Install
 
-1. Install the Hugo Module by adding the following to the bottom of your `config/_default/config.toml`:
+1. Edit `config/_default/config.toml` to install the `wowchemy-cms` Hugo Module so that you have something like:
 
-    ```toml
-    [module]
-      # Any existing modules here...
-      [[module.imports]]
-        path = "github.com/wowchemy/wowchemy-hugo-modules/wowchemy-cms"
-      [[module.imports]]
-        path = "github.com/wowchemy/wowchemy-hugo-modules/wowchemy"
-    ```
+   ```toml
+   [module]
+     # Any existing modules here...
+     [[module.imports]]
+       path = "github.com/wowchemy/wowchemy-hugo-modules/wowchemy-cms"
+     [[module.imports]]
+       path = "github.com/wowchemy/wowchemy-hugo-modules/wowchemy"
+   ```
 
 2. Create a `content/admin/index.md` file containing:
 
@@ -24,5 +24,7 @@ Built upon the open source [Netlify CMS](https://www.netlifycms.org/) and [Netli
 type: wowchemycms
 outputs:
   - wowchemycms_config
+  - HTML
 ---
+
 ```

+ 4 - 2
wowchemy-cms/config.yaml

@@ -1,7 +1,9 @@
 module:
   mounts:
-    - source: static
-      target: static
+    - source: data
+      target: data
+    - source: functions
+      target: layouts/partials/mod-wowchemy-cms
     - source: templates
       target: layouts/wowchemycms
 outputFormats:

+ 521 - 0
wowchemy-cms/data/wowchemy_cms_tpl.yaml

@@ -0,0 +1,521 @@
+backend:
+  name: git-gateway
+  branch: main
+  squash_merges: true
+media_folder: 'static/media'
+public_folder: '/media'
+collections:
+  - name: home
+    label: "Homepage"
+    folder: 'content/home'
+    path: '{{slug}}'
+    # When specifying a path on a folder collection, media_folder defaults to an empty string, so make it explicit.
+    media_folder: '/static/media'
+    public_folder: ''
+    summary: "{{filename}}: {{title}}"
+    identifier_field: "widget_id"
+    create: true
+    fields:
+      - {label: "Widget Type (https://wowchemy.com/docs/page-builder/)", name: "widget", widget: "string", required: true}
+      - {label: 'Your reference for this widget (e.g. recent-posts)', name: 'widget_id', widget: 'string', default: 'my-widget-123'}
+      - {label: "Headless?", name: "headless", widget: "hidden", default: true}
+      - label: "Widget position"
+        name: "weight"
+        widget: "number"
+        default: 10
+        value_type: "int"
+        min: 0
+        max: 1001
+        step: 10
+      - {label: "Title", name: "title", widget: "string", required: false}
+      - {label: "Subtitle", name: "subtitle", widget: "string", required: false}
+      - label: "Enabled?"
+        name: "active"
+        required: false
+        widget: "boolean"
+        default: true
+      - label: "Widget Style"
+        name: "design"
+        widget: "object"
+        required: false
+        fields:
+          - {label: "Columns (options: `1` or `2`)", name: "columns", widget: "string", default: "2", required: false}
+          - label: "Background"
+            name: "background"
+            widget: "object"
+            required: false
+            fields:
+              - {label: 'Solid color', name: 'color', widget: 'color', enableAlpha: true, allowInput: true, required: false}
+              - {label: 'Gradient start', name: 'gradient_start', widget: 'color', enableAlpha: true, allowInput: true, required: false}
+              - {label: 'Gradient end', name: 'gradient_end', widget: 'color', enableAlpha: true, allowInput: true, required: false}
+              - label: "Use a light text color?"
+                name: "text_color_light"
+                required: false
+                widget: "boolean"
+                default: false
+              - label: "Image"
+                name: "image"
+                widget: "image"
+                required: false
+                # When specifying a path on a folder collection, media_folder defaults to an empty string, so make it explicit.
+                media_folder: '/static/media'
+                public_folder: ''
+                media_library:
+                  config:
+                    multiple: false
+              - label: "Darken the image? (0 is transparent & 1 is opaque)"
+                name: "image_darken"
+                widget: "number"
+                default: 0.0
+                value_type: "float"
+                min: 0.0
+                max: 1.0
+                step: 0.1
+                required: false
+      - {label: "Body", name: "body", widget: "markdown", required: false}
+  - name: authors
+    label: Authors
+    label_singular: Author
+    folder: 'content/authors'
+    path: '{{slug}}/_index'
+    filter: {field: "cms_exclude"}
+    create: true  # Allow users to create new documents in this collection
+    fields:  # The fields each document in this collection have
+      - {label: "Display name (such as your full name)", name: "title", widget: "string"}
+      - {label: "Position or tagline (such as Professor of AI)", name: "role", widget: "string", required: false}
+      - label: "Avatar (upload an image named `avatar.jpg/png`)"
+        name: "avatar_filename"
+        widget: "image"
+        default: "avatar"
+        required: false
+        media_library:
+          config:
+            multiple: false
+      - {label: "Short biography (shown in author boxes)", name: "bio", widget: "string", required: false}
+      - {label: "Full biography (shown in About widget)", name: "body", widget: "markdown", required: false}
+      - label: "Interests (shown in About widget)"
+        name: "interests"
+        required: false
+        widget: "list"
+      - label: Social links
+        name: social
+        required: false
+        widget: list
+        fields:
+          - {label: Link, name: link, widget: string}
+          - label: Icon pack
+            name: icon_pack
+            widget: select
+            multiple: false
+            options:
+              - {label: "None", value: ""}
+              - {label: "Solid", value: "fas"}
+              - {label: "Regular", value: "far"}
+              - {label: "Brand", value: "fab"}
+              - {label: "Academic", value: "ai"}
+          - {label: Icon (see https://wowchemy.com/docs/page-builder/#icons), name: icon, widget: string}
+          - {label: Label (tooltip), name: label, widget: string, required: false}
+          - label: Display in About widget and...
+            name: display
+            widget: object
+            fields:
+              - label: "Header (main menu)"
+                name: "header"
+                widget: "boolean"
+                default: false
+                required: false
+      - label: "Organizations you belong to or are affiliated with (shown in About widget)"
+        name: "organizations"
+        required: false
+        widget: list
+        fields:
+          - {label: Organization, name: name, widget: string, required: true}
+          - {label: Link, name: url, widget: string, required: false}
+      - label: "Education"
+        name: "education"
+        required: false
+        widget: object
+        fields:
+          - label: "Courses"
+            name: "courses"
+            required: false
+            widget: list
+            fields:
+              - {label: Course, name: course, widget: string, required: true}
+              - {label: Institution, name: institution, widget: string, required: true}
+              - {label: Year, name: year, widget: number, value_type: int, required: false}
+      - {label: "Email (to use a Gravatar.com avatar)", name: "email", widget: "string", required: false}
+      - label: "Super user (is this the primary site user?)"
+        name: "superuser"
+        widget: "boolean"
+        default: false
+      - label: "User groups (only for organization websites)"
+        name: "user_groups"
+        required: false
+        widget: "list"
+  - name: posts
+    label: Posts
+    label_singular: Post
+    folder: 'content/post'
+    path: '{{slug}}/index'
+    filter: {field: "cms_exclude"}
+    create: true  # Allow users to create new documents in this collection
+    fields:  # The fields each document in this collection have
+      - {label: "Title", name: "title", widget: "string"}
+      - {label: "Subtitle", name: "subtitle", widget: "string", required: false}
+      - {label: "Body", name: "body", widget: "markdown"}
+      - {label: "Publish this page on", name: "date", widget: "datetime"}
+      - {label: "Summary", name: "summary", widget: "markdown", required: false}
+      - label: "Draft"
+        name: "draft"
+        widget: "boolean"
+        default: false
+        required: false
+      - label: "Featured"
+        name: "featured"
+        widget: "boolean"
+        default: false
+        required: false
+      - label: "Authors"
+        name: "authors"
+        required: false
+        widget: "list"
+      - label: "Tags"
+        name: "tags"
+        required: false
+        widget: "list"
+      - label: "Categories"
+        name: "categories"
+        required: false
+        widget: "list"
+      - label: "Projects"
+        name: "projects"
+        required: false
+        widget: "list"
+      - label: "Featured Image"
+        name: "image"
+        required: false
+        widget: object
+        fields:
+          - label: "Upload an image named `featured.jpg/png`"
+            name: "filename"
+            widget: "image"
+            default: "featured"
+            required: false
+            media_library:
+              config:
+                multiple: false
+          - {label: Caption, name: caption, widget: string, required: false}
+          - {label: Description for screen readers, name: alt_text, widget: string, required: false}
+          - {label: "Where's the focal point in the image? Smart, Center, TopLeft, Top, TopRight, Left, Right, BottomLeft, Bottom, BottomRight.", name: focal_point, widget: string, required: false, default: "Smart"}
+          - {label: 'Thumbnail Only?', name: preview_only, widget: boolean, default: false, required: false}
+  - name: projects
+    label: Projects
+    label_singular: Project
+    folder: 'content/project'
+    path: '{{slug}}/index'
+    filter: {field: "cms_exclude"}
+    create: true  # Allow users to create new documents in this collection
+    fields:  # The fields each document in this collection have
+      - {label: "Title", name: "title", widget: "string"}
+      - {label: "Subtitle", name: "subtitle", widget: "string", required: false}
+      - {label: "Body", name: "body", widget: "markdown", required: false}
+      - {label: "Publish this page on", name: "date", widget: "datetime"}
+      - {label: "Summary", name: "summary", widget: "markdown", required: false}
+      - label: "Draft"
+        name: "draft"
+        widget: "boolean"
+        default: false
+        required: false
+      - label: "Featured"
+        name: "featured"
+        widget: "boolean"
+        default: false
+        required: false
+      - label: "Authors"
+        name: "authors"
+        required: false
+        widget: "list"
+      - label: "Tags"
+        name: "tags"
+        required: false
+        widget: "list"
+      - label: "Categories"
+        name: "categories"
+        required: false
+        widget: "list"
+      - {label: "External link (optional - replaces link to project page)", name: "external_link", widget: "string"}
+      - label: Links
+        name: links
+        required: false
+        widget: list
+        fields:
+          - {label: Link, name: url, widget: string}
+          - {label: Link text, name: name, widget: string, required: false}
+          - label: Icon pack
+            name: icon_pack
+            widget: select
+            multiple: false
+            required: false
+            options:
+              - {label: "None", value: ""}
+              - {label: "Solid", value: "fas"}
+              - {label: "Regular", value: "far"}
+              - {label: "Brand", value: "fab"}
+              - {label: "Academic", value: "ai"}
+          - {label: "Icon (see https://wowchemy.com/docs/page-builder/#icons)", name: icon, widget: string, required: false}
+      - label: "Featured Image"
+        name: "image"
+        required: false
+        widget: object
+        fields:
+          - label: "Upload an image named `featured.jpg/png`"
+            name: "filename"
+            widget: "image"
+            default: "featured"
+            required: false
+            media_library:
+              config:
+                multiple: false
+          - {label: Caption, name: caption, widget: string, required: false}
+          - {label: Description for screen readers, name: alt_text, widget: string, required: false}
+          - {label: "Where's the focal point in the image? Smart, Center, TopLeft, Top, TopRight, Left, Right, BottomLeft, Bottom, BottomRight.", name: focal_point, widget: string, required: false, default: "Smart"}
+          - {label: 'Thumbnail Only?', name: preview_only, widget: boolean, default: false, required: false}
+  - name: events
+    label: Events
+    label_singular: Event
+    folder: 'content/event'
+    path: '{{slug}}/index'
+    filter: {field: "cms_exclude"}
+    create: true  # Allow users to create new documents in this collection
+    fields:  # The fields each document in this collection have
+      - {label: "Title", name: "title", widget: "string"}
+      - {label: "Abstract", name: "abstract", widget: "text"}
+      - {label: "Where", name: "location", widget: "text"}
+      - {label: "From", name: "date", widget: "datetime"}
+      - {label: "To", name: "date_end", widget: "datetime", default: ""}
+      - {label: "All day event?", name: "all_day", widget: "boolean", default: false}
+      - label: Links/Tickets
+        name: links
+        required: false
+        widget: list
+        fields:
+          - {label: Link, name: url, widget: string}
+          - {label: Link text, name: name, widget: string, required: false}
+          - label: Icon pack
+            name: icon_pack
+            widget: select
+            multiple: false
+            required: false
+            options:
+              - {label: "None", value: ""}
+              - {label: "Solid", value: "fas"}
+              - {label: "Regular", value: "far"}
+              - {label: "Brand", value: "fab"}
+              - {label: "Academic", value: "ai"}
+          - {label: "Icon (see https://wowchemy.com/docs/page-builder/#icons)", name: icon, widget: string, required: false}
+      - {label: "Event", name: "event", widget: "string"}
+      - {label: "Event link", name: "event_url", widget: "string"}
+      - {label: "Publish this page on", name: "publishDate", widget: "datetime"}
+      - {label: "Markdown slides (reference a deck in 'content/slides/')", name: "slides", widget: "string", required: false}
+      - label: "Draft"
+        name: "draft"
+        widget: "boolean"
+        default: false
+        required: false
+      - label: "Featured"
+        name: "featured"
+        widget: "boolean"
+        default: false
+        required: false
+      - label: "Authors"
+        name: "authors"
+        required: false
+        widget: "list"
+      - label: "Tags"
+        name: "tags"
+        required: false
+        widget: "list"
+      - label: "Categories"
+        name: "categories"
+        required: false
+        widget: "list"
+      - label: "Projects (reference projects in 'content/project/')"
+        name: "projects"
+        required: false
+        widget: "list"
+      - label: "Featured Image"
+        name: "image"
+        required: false
+        widget: object
+        fields:
+          - label: "Upload an image named `featured.jpg/png`"
+            name: "filename"
+            widget: "image"
+            default: "featured"
+            required: false
+            media_library:
+              config:
+                multiple: false
+          - {label: Caption, name: caption, widget: string, required: false}
+          - {label: Description for screen readers, name: alt_text, widget: string, required: false}
+          - {label: "Where's the focal point in the image? Smart, Center, TopLeft, Top, TopRight, Left, Right, BottomLeft, Bottom, BottomRight.", name: focal_point, widget: string, required: false, default: "Smart"}
+          - {label: 'Thumbnail Only?', name: preview_only, widget: boolean, default: false, required: false}
+      - {label: "Details", name: "body", widget: "markdown", required: false}
+  - name: publications
+    label: Publications
+    label_singular: Publication
+    folder: 'content/publication'
+    path: '{{slug}}/index'
+    filter: {field: "cms_exclude"}
+    create: true  # Allow users to create new documents in this collection
+    fields: # The fields each document in this collection have
+      - { label: "Title", name: "title", widget: "string" }
+      - { label: "Subtitle", name: "subtitle", widget: "string", required: false }
+      - label: "Publication type"
+        name: "publication_types"
+        required: true
+        default: ["0"]
+        widget: "select"
+        # Can only have 1 pub. type assigned, but need `multiple` option to save as a Hugo taxonomy list.
+        multiple: true
+        options:
+          - { label: "Uncategorized", value: "0" }
+          - { label: "Conference paper", value: "1" }
+          - { label: "Journal article", value: "2" }
+          - { label: "Preprint / Working Paper", value: "3" }
+          - { label: "Report", value: "4" }
+          - { label: "Book", value: "5" }
+          - { label: "Book section", value: "6" }
+          - { label: "Thesis", value: "7" }
+          - { label: "Patent", value: "8" }
+      - label: "Authors"
+        name: "authors"
+        required: true
+        widget: "list"
+      - label: "Author Notes (contributions or affiliations for each author)"
+        name: "author_notes"
+        required: false
+        widget: "list"
+      - { label: "DOI", name: "doi", widget: "string", required: false }
+      - { label: "Publication", name: "publication", widget: "string", required: false }
+      - { label: "Publication (abbreviated)", name: "publication_short", widget: "string", required: false }
+      - { label: "Abstract", name: "abstract", widget: "text", required: false }
+      - label: "Draft"
+        name: "draft"
+        widget: "boolean"
+        default: false
+        required: false
+      - label: "Featured"
+        name: "featured"
+        widget: "boolean"
+        default: false
+        required: false
+      - label: "Tags"
+        name: "tags"
+        required: false
+        widget: "list"
+      - label: "Categories"
+        name: "categories"
+        required: false
+        widget: "list"
+      - label: "Projects"
+        name: "projects"
+        required: false
+        widget: "list"
+      - {label: "Markdown slides (reference a deck in 'content/slides/')", name: "slides", widget: "string", required: false}
+      - label: "Featured Image"
+        name: "image"
+        required: false
+        widget: object
+        fields:
+          - label: "Upload an image named `featured.jpg/png`"
+            name: "filename"
+            widget: "image"
+            default: "featured"
+            required: false
+            media_library:
+              config:
+                multiple: false
+          - { label: Caption, name: caption, widget: string, required: false }
+          - { label: Description for screen readers, name: alt_text, widget: string, required: false }
+          - { label: "Where's the focal point in the image? Smart, Center, TopLeft, Top, TopRight, Left, Right, BottomLeft, Bottom, BottomRight.", name: focal_point, widget: string, required: false, default: "Smart" }
+          - { label: 'Thumbnail Only?', name: preview_only, widget: boolean, default: false, required: false }
+      - { label: "Summary (shortened abstract)", name: "summary", widget: "text", required: false }
+      - {label: "Details", name: "body", widget: "markdown", required: false}
+      - { label: "Publish this page on", name: "date", widget: "datetime" }
+  - name: slides
+    label: Slides
+    label_singular: Slides
+    folder: 'content/slides'
+    path: '{{slug}}/index'
+    filter: {field: "cms_exclude"}
+    create: true  # Allow users to create new documents in this collection
+    fields:  # The fields each document in this collection have
+      - {label: "Title", name: "title", widget: "string"}
+      - {label: "Slides (separate with `---`)", name: "body", widget: "markdown"}
+      - {label: "Publish on", name: "date", widget: "datetime"}
+      - {label: "Summary", name: "summary", widget: "text", required: false}
+      - label: "Draft"
+        name: "draft"
+        widget: "boolean"
+        default: false
+        required: false
+      - label: "Tags"
+        name: "tags"
+        required: false
+        widget: "list"
+      - label: "Slide options"
+        name: "slides"
+        required: false
+        widget: object
+        fields:
+          - { label: "Theme (see https://github.com/hakimel/reveal.js#theming)", name: theme, widget: string, required: false, default: black }
+      - label: "Featured Image"
+        name: "image"
+        required: false
+        widget: object
+        fields:
+          - label: "Upload an image named `featured.jpg/png`"
+            name: "filename"
+            widget: "image"
+            default: "featured"
+            required: false
+            media_library:
+              config:
+                multiple: false
+          - {label: Caption, name: caption, widget: string, required: false}
+          - {label: Description for screen readers, name: alt_text, widget: string, required: false}
+          - {label: "Where's the focal point in the image? Smart, Center, TopLeft, Top, TopRight, Left, Right, BottomLeft, Bottom, BottomRight.", name: focal_point, widget: string, required: false, default: "Smart"}
+          - {label: 'Thumbnail Only?', name: preview_only, widget: boolean, default: false, required: false}
+  - name: pages
+    label: "Pages"
+    files:
+      - file: "content/privacy.md"
+        label: "Privacy Policy"
+        name: "privacy"
+        fields:
+          - {label: "Title", name: "title", widget: "string"}
+          - {label: "Publish Date", name: "date", widget: "datetime"}
+          - {label: "Subtitle", name: "subtitle", widget: "string", required: false}
+          - {label: "Summary", name: "summary", widget: "markdown", required: false}
+          - label: "Draft"
+            name: "draft"
+            required: false
+            widget: "boolean"
+            default: false
+          - {label: "Body", name: "body", widget: "markdown"}
+      - file: "content/terms.md"
+        label: "Terms"
+        name: "terms"
+        fields:
+          - {label: "Title", name: "title", widget: "string"}
+          - {label: "Publish Date", name: "date", widget: "datetime"}
+          - {label: "Subtitle", name: "subtitle", widget: "string", required: false}
+          - {label: "Summary", name: "summary", widget: "markdown", required: false}
+          - label: "Draft"
+            name: "draft"
+            required: false
+            widget: "boolean"
+            default: false
+          - {label: "Body", name: "body", widget: "markdown"}

+ 8 - 0
wowchemy-cms/functions/generate.html

@@ -0,0 +1,8 @@
+{{ $config := dict }}
+{{ with partialCached "mod-wowchemy-cms/parse" . "mod-wowchemy-cms/parse" }}
+  {{ $config = . }}
+{{ end }}
+
+{{ $return := transform.Remarshal "yaml" $config }}
+
+{{ return $return }}

+ 21 - 0
wowchemy-cms/functions/parse.html

@@ -0,0 +1,21 @@
+{{ $return := "" }}
+{{ with site.Data.wowchemy_cms_tpl }}
+  {{ $return = . }}
+{{ end }}
+
+{{ $backend_opts := dict "branch" (site.Params.cms.branch | default "main") }}
+
+{{ with site.Params.cms.publish_mode }}
+  {{ $publish_mode := dict "publish_mode" . }}
+  {{ $backend_opts = merge $backend $publish_mode }}
+{{ end }}
+
+{{ if site.Params.cms.local_backend }}
+  {{ $local_backend := dict "local_backend" true }}
+  {{ $return = merge $return $local_backend }}
+{{ end }}
+
+{{ $backend := dict "backend" $backend_opts }}
+{{ $return := merge $return $backend }}
+
+{{- return $return -}}

+ 2 - 2
wowchemy-cms/static/admin/index.html → wowchemy-cms/templates/single.html

@@ -1,10 +1,10 @@
 <!doctype html>
 <html lang="en-us">
 <head>
-  <meta name="robots" content="noindex">
+  <meta content="noindex" name="robots">
   <meta charset="utf-8">
   <meta content="width=device-width, initial-scale=1.0" name="viewport">
-  <title>Wowchemy Content Manager</title>
+  <title>Wowchemy CMS</title>
   <!-- Include Netlify Identity for authentication. -->
   <script src="https://identity.netlify.com/v1/netlify-identity-widget.js"></script>
 </head>

+ 3 - 521
wowchemy-cms/templates/single.wowchemycms_config.yml

@@ -1,521 +1,3 @@
-backend:
-  name: git-gateway
-  branch: main
-  squash_merges: true
-media_folder: 'static/media'
-public_folder: '/media'
-collections:
-  - name: home
-    label: "Homepage"
-    folder: 'content/home'
-    path: '{{slug}}'
-    # When specifying a path on a folder collection, media_folder defaults to an empty string, so make it explicit.
-    media_folder: '/static/media'
-    public_folder: ''
-    summary: "{{filename}}: {{title}}"
-    identifier_field: "widget_id"
-    create: true
-    fields:
-      - {label: "Widget Type (https://wowchemy.com/docs/page-builder/)", name: "widget", widget: "string", required: true}
-      - {label: 'Your reference for this widget (e.g. recent-posts)', name: 'widget_id', widget: 'string', default: 'my-widget-123'}
-      - {label: "Headless?", name: "headless", widget: "hidden", default: true}
-      - label: "Widget position"
-        name: "weight"
-        widget: "number"
-        default: 10
-        value_type: "int"
-        min: 0
-        max: 1001
-        step: 10
-      - {label: "Title", name: "title", widget: "string", required: false}
-      - {label: "Subtitle", name: "subtitle", widget: "string", required: false}
-      - label: "Enabled?"
-        name: "active"
-        required: false
-        widget: "boolean"
-        default: true
-      - label: "Widget Style"
-        name: "design"
-        widget: "object"
-        required: false
-        fields:
-          - {label: "Columns (options: `1` or `2`)", name: "columns", widget: "string", default: "2", required: false}
-          - label: "Background"
-            name: "background"
-            widget: "object"
-            required: false
-            fields:
-              - {label: 'Solid color', name: 'color', widget: 'color', enableAlpha: true, allowInput: true, required: false}
-              - {label: 'Gradient start', name: 'gradient_start', widget: 'color', enableAlpha: true, allowInput: true, required: false}
-              - {label: 'Gradient end', name: 'gradient_end', widget: 'color', enableAlpha: true, allowInput: true, required: false}
-              - label: "Use a light text color?"
-                name: "text_color_light"
-                required: false
-                widget: "boolean"
-                default: false
-              - label: "Image"
-                name: "image"
-                widget: "image"
-                required: false
-                # When specifying a path on a folder collection, media_folder defaults to an empty string, so make it explicit.
-                media_folder: '/static/media'
-                public_folder: ''
-                media_library:
-                  config:
-                    multiple: false
-              - label: "Darken the image? (0 is transparent & 1 is opaque)"
-                name: "image_darken"
-                widget: "number"
-                default: 0.0
-                value_type: "float"
-                min: 0.0
-                max: 1.0
-                step: 0.1
-                required: false
-      - {label: "Body", name: "body", widget: "markdown", required: false}
-  - name: authors
-    label: Authors
-    label_singular: Author
-    folder: 'content/authors'
-    path: '{{slug}}/_index'
-    filter: {field: "cms_exclude"}
-    create: true  # Allow users to create new documents in this collection
-    fields:  # The fields each document in this collection have
-      - {label: "Display name (such as your full name)", name: "title", widget: "string"}
-      - {label: "Position or tagline (such as Professor of AI)", name: "role", widget: "string", required: false}
-      - label: "Avatar (upload an image named `avatar.jpg/png`)"
-        name: "avatar_filename"
-        widget: "image"
-        default: "avatar"
-        required: false
-        media_library:
-          config:
-            multiple: false
-      - {label: "Short biography (shown in author boxes)", name: "bio", widget: "string", required: false}
-      - {label: "Full biography (shown in About widget)", name: "body", widget: "markdown", required: false}
-      - label: "Interests (shown in About widget)"
-        name: "interests"
-        required: false
-        widget: "list"
-      - label: Social links
-        name: social
-        required: false
-        widget: list
-        fields:
-          - {label: Link, name: link, widget: string}
-          - label: Icon pack
-            name: icon_pack
-            widget: select
-            multiple: false
-            options:
-              - {label: "None", value: ""}
-              - {label: "Solid", value: "fas"}
-              - {label: "Regular", value: "far"}
-              - {label: "Brand", value: "fab"}
-              - {label: "Academic", value: "ai"}
-          - {label: Icon (see https://wowchemy.com/docs/page-builder/#icons), name: icon, widget: string}
-          - {label: Label (tooltip), name: label, widget: string, required: false}
-          - label: Display in About widget and...
-            name: display
-            widget: object
-            fields:
-            - label: "Header (main menu)"
-              name: "header"
-              widget: "boolean"
-              default: false
-              required: false
-      - label: "Organizations you belong to or are affiliated with (shown in About widget)"
-        name: "organizations"
-        required: false
-        widget: list
-        fields:
-          - {label: Organization, name: name, widget: string, required: true}
-          - {label: Link, name: url, widget: string, required: false}
-      - label: "Education"
-        name: "education"
-        required: false
-        widget: object
-        fields:
-          - label: "Courses"
-            name: "courses"
-            required: false
-            widget: list
-            fields:
-              - {label: Course, name: course, widget: string, required: true}
-              - {label: Institution, name: institution, widget: string, required: true}
-              - {label: Year, name: year, widget: number, value_type: int, required: false}
-      - {label: "Email (to use a Gravatar.com avatar)", name: "email", widget: "string", required: false}
-      - label: "Super user (is this the primary site user?)"
-        name: "superuser"
-        widget: "boolean"
-        default: false
-      - label: "User groups (only for organization websites)"
-        name: "user_groups"
-        required: false
-        widget: "list"
-  - name: posts
-    label: Posts
-    label_singular: Post
-    folder: 'content/post'
-    path: '{{slug}}/index'
-    filter: {field: "cms_exclude"}
-    create: true  # Allow users to create new documents in this collection
-    fields:  # The fields each document in this collection have
-      - {label: "Title", name: "title", widget: "string"}
-      - {label: "Subtitle", name: "subtitle", widget: "string", required: false}
-      - {label: "Body", name: "body", widget: "markdown"}
-      - {label: "Publish this page on", name: "date", widget: "datetime"}
-      - {label: "Summary", name: "summary", widget: "markdown", required: false}
-      - label: "Draft"
-        name: "draft"
-        widget: "boolean"
-        default: false
-        required: false
-      - label: "Featured"
-        name: "featured"
-        widget: "boolean"
-        default: false
-        required: false
-      - label: "Authors"
-        name: "authors"
-        required: false
-        widget: "list"
-      - label: "Tags"
-        name: "tags"
-        required: false
-        widget: "list"
-      - label: "Categories"
-        name: "categories"
-        required: false
-        widget: "list"
-      - label: "Projects"
-        name: "projects"
-        required: false
-        widget: "list"
-      - label: "Featured Image"
-        name: "image"
-        required: false
-        widget: object
-        fields:
-          - label: "Upload an image named `featured.jpg/png`"
-            name: "filename"
-            widget: "image"
-            default: "featured"
-            required: false
-            media_library:
-              config:
-                multiple: false
-          - {label: Caption, name: caption, widget: string, required: false}
-          - {label: Description for screen readers, name: alt_text, widget: string, required: false}
-          - {label: "Where's the focal point in the image? Smart, Center, TopLeft, Top, TopRight, Left, Right, BottomLeft, Bottom, BottomRight.", name: focal_point, widget: string, required: false, default: "Smart"}
-          - {label: Thumbnail Only?, name: preview_only, widget: boolean, default: false, required: false}
-  - name: projects
-    label: Projects
-    label_singular: Project
-    folder: 'content/project'
-    path: '{{slug}}/index'
-    filter: {field: "cms_exclude"}
-    create: true  # Allow users to create new documents in this collection
-    fields:  # The fields each document in this collection have
-      - {label: "Title", name: "title", widget: "string"}
-      - {label: "Subtitle", name: "subtitle", widget: "string", required: false}
-      - {label: "Body", name: "body", widget: "markdown", required: false}
-      - {label: "Publish this page on", name: "date", widget: "datetime"}
-      - {label: "Summary", name: "summary", widget: "markdown", required: false}
-      - label: "Draft"
-        name: "draft"
-        widget: "boolean"
-        default: false
-        required: false
-      - label: "Featured"
-        name: "featured"
-        widget: "boolean"
-        default: false
-        required: false
-      - label: "Authors"
-        name: "authors"
-        required: false
-        widget: "list"
-      - label: "Tags"
-        name: "tags"
-        required: false
-        widget: "list"
-      - label: "Categories"
-        name: "categories"
-        required: false
-        widget: "list"
-      - {label: "External link (optional - replaces link to project page)", name: "external_link", widget: "string"}
-      - label: Links
-        name: links
-        required: false
-        widget: list
-        fields:
-          - {label: Link, name: url, widget: string}
-          - {label: Link text, name: name, widget: string, required: false}
-          - label: Icon pack
-            name: icon_pack
-            widget: select
-            multiple: false
-            required: false
-            options:
-              - {label: "None", value: ""}
-              - {label: "Solid", value: "fas"}
-              - {label: "Regular", value: "far"}
-              - {label: "Brand", value: "fab"}
-              - {label: "Academic", value: "ai"}
-          - {label: "Icon (see https://wowchemy.com/docs/page-builder/#icons)", name: icon, widget: string, required: false}
-      - label: "Featured Image"
-        name: "image"
-        required: false
-        widget: object
-        fields:
-          - label: "Upload an image named `featured.jpg/png`"
-            name: "filename"
-            widget: "image"
-            default: "featured"
-            required: false
-            media_library:
-              config:
-                multiple: false
-          - {label: Caption, name: caption, widget: string, required: false}
-          - {label: Description for screen readers, name: alt_text, widget: string, required: false}
-          - {label: "Where's the focal point in the image? Smart, Center, TopLeft, Top, TopRight, Left, Right, BottomLeft, Bottom, BottomRight.", name: focal_point, widget: string, required: false, default: "Smart"}
-          - {label: Thumbnail Only?, name: preview_only, widget: boolean, default: false, required: false}
-  - name: events
-    label: Events
-    label_singular: Event
-    folder: 'content/event'
-    path: '{{slug}}/index'
-    filter: {field: "cms_exclude"}
-    create: true  # Allow users to create new documents in this collection
-    fields:  # The fields each document in this collection have
-      - {label: "Title", name: "title", widget: "string"}
-      - {label: "Abstract", name: "abstract", widget: "text"}
-      - {label: "Where", name: "location", widget: "text"}
-      - {label: "From", name: "date", widget: "datetime"}
-      - {label: "To", name: "date_end", widget: "datetime", default: ""}
-      - {label: "All day event?", name: "all_day", widget: "boolean", default: false}
-      - label: Links/Tickets
-        name: links
-        required: false
-        widget: list
-        fields:
-          - {label: Link, name: url, widget: string}
-          - {label: Link text, name: name, widget: string, required: false}
-          - label: Icon pack
-            name: icon_pack
-            widget: select
-            multiple: false
-            required: false
-            options:
-              - {label: "None", value: ""}
-              - {label: "Solid", value: "fas"}
-              - {label: "Regular", value: "far"}
-              - {label: "Brand", value: "fab"}
-              - {label: "Academic", value: "ai"}
-          - {label: "Icon (see https://wowchemy.com/docs/page-builder/#icons)", name: icon, widget: string, required: false}
-      - {label: "Event", name: "event", widget: "string"}
-      - {label: "Event link", name: "event_url", widget: "string"}
-      - {label: "Publish this page on", name: "publishDate", widget: "datetime"}
-      - {label: "Markdown slides (reference a deck in 'content/slides/')", name: "slides", widget: "string", required: false}
-      - label: "Draft"
-        name: "draft"
-        widget: "boolean"
-        default: false
-        required: false
-      - label: "Featured"
-        name: "featured"
-        widget: "boolean"
-        default: false
-        required: false
-      - label: "Authors"
-        name: "authors"
-        required: false
-        widget: "list"
-      - label: "Tags"
-        name: "tags"
-        required: false
-        widget: "list"
-      - label: "Categories"
-        name: "categories"
-        required: false
-        widget: "list"
-      - label: "Projects (reference projects in 'content/project/')"
-        name: "projects"
-        required: false
-        widget: "list"
-      - label: "Featured Image"
-        name: "image"
-        required: false
-        widget: object
-        fields:
-          - label: "Upload an image named `featured.jpg/png`"
-            name: "filename"
-            widget: "image"
-            default: "featured"
-            required: false
-            media_library:
-              config:
-                multiple: false
-          - {label: Caption, name: caption, widget: string, required: false}
-          - {label: Description for screen readers, name: alt_text, widget: string, required: false}
-          - {label: "Where's the focal point in the image? Smart, Center, TopLeft, Top, TopRight, Left, Right, BottomLeft, Bottom, BottomRight.", name: focal_point, widget: string, required: false, default: "Smart"}
-          - {label: Thumbnail Only?, name: preview_only, widget: boolean, default: false, required: false}
-      - {label: "Details", name: "body", widget: "markdown", required: false}
-  - name: publications
-    label: Publications
-    label_singular: Publication
-    folder: 'content/publication'
-    path: '{{slug}}/index'
-    filter: {field: "cms_exclude"}
-    create: true  # Allow users to create new documents in this collection
-    fields: # The fields each document in this collection have
-      - { label: "Title", name: "title", widget: "string" }
-      - { label: "Subtitle", name: "subtitle", widget: "string", required: false }
-      - label: "Publication type"
-        name: "publication_types"
-        required: true
-        default: ["0"]
-        widget: "select"
-        # Can only have 1 pub. type assigned, but need `multiple` option to save as a Hugo taxonomy list.
-        multiple: true
-        options:
-          - { label: "Uncategorized", value: "0" }
-          - { label: "Conference paper", value: "1" }
-          - { label: "Journal article", value: "2" }
-          - { label: "Preprint / Working Paper", value: "3" }
-          - { label: "Report", value: "4" }
-          - { label: "Book", value: "5" }
-          - { label: "Book section", value: "6" }
-          - { label: "Thesis", value: "7" }
-          - { label: "Patent", value: "8" }
-      - label: "Authors"
-        name: "authors"
-        required: true
-        widget: "list"
-      - label: "Author Notes (contributions or affiliations for each author)"
-        name: "author_notes"
-        required: false
-        widget: "list"
-      - { label: "DOI", name: "doi", widget: "string", required: false }
-      - { label: "Publication", name: "publication", widget: "string", required: false }
-      - { label: "Publication (abbreviated)", name: "publication_short", widget: "string", required: false }
-      - { label: "Abstract", name: "abstract", widget: "text", required: false }
-      - label: "Draft"
-        name: "draft"
-        widget: "boolean"
-        default: false
-        required: false
-      - label: "Featured"
-        name: "featured"
-        widget: "boolean"
-        default: false
-        required: false
-      - label: "Tags"
-        name: "tags"
-        required: false
-        widget: "list"
-      - label: "Categories"
-        name: "categories"
-        required: false
-        widget: "list"
-      - label: "Projects"
-        name: "projects"
-        required: false
-        widget: "list"
-      - {label: "Markdown slides (reference a deck in 'content/slides/')", name: "slides", widget: "string", required: false}
-      - label: "Featured Image"
-        name: "image"
-        required: false
-        widget: object
-        fields:
-          - label: "Upload an image named `featured.jpg/png`"
-            name: "filename"
-            widget: "image"
-            default: "featured"
-            required: false
-            media_library:
-              config:
-                multiple: false
-          - { label: Caption, name: caption, widget: string, required: false }
-          - { label: Description for screen readers, name: alt_text, widget: string, required: false }
-          - { label: "Where's the focal point in the image? Smart, Center, TopLeft, Top, TopRight, Left, Right, BottomLeft, Bottom, BottomRight.", name: focal_point, widget: string, required: false, default: "Smart" }
-          - { label: Thumbnail Only?, name: preview_only, widget: boolean, default: false, required: false }
-      - { label: "Summary (shortened abstract)", name: "summary", widget: "text", required: false }
-      - {label: "Details", name: "body", widget: "markdown", required: false}
-      - { label: "Publish this page on", name: "date", widget: "datetime" }
-  - name: slides
-    label: Slides
-    label_singular: Slides
-    folder: 'content/slides'
-    path: '{{slug}}/index'
-    filter: {field: "cms_exclude"}
-    create: true  # Allow users to create new documents in this collection
-    fields:  # The fields each document in this collection have
-      - {label: "Title", name: "title", widget: "string"}
-      - {label: "Slides (separate with `---`)", name: "body", widget: "markdown"}
-      - {label: "Publish on", name: "date", widget: "datetime"}
-      - {label: "Summary", name: "summary", widget: "text", required: false}
-      - label: "Draft"
-        name: "draft"
-        widget: "boolean"
-        default: false
-        required: false
-      - label: "Tags"
-        name: "tags"
-        required: false
-        widget: "list"
-      - label: "Slide options"
-        name: "slides"
-        required: false
-        widget: object
-        fields:
-          - { label: "Theme (see https://github.com/hakimel/reveal.js#theming)", name: theme, widget: string, required: false, default: black }
-      - label: "Featured Image"
-        name: "image"
-        required: false
-        widget: object
-        fields:
-          - label: "Upload an image named `featured.jpg/png`"
-            name: "filename"
-            widget: "image"
-            default: "featured"
-            required: false
-            media_library:
-              config:
-                multiple: false
-          - {label: Caption, name: caption, widget: string, required: false}
-          - {label: Description for screen readers, name: alt_text, widget: string, required: false}
-          - {label: "Where's the focal point in the image? Smart, Center, TopLeft, Top, TopRight, Left, Right, BottomLeft, Bottom, BottomRight.", name: focal_point, widget: string, required: false, default: "Smart"}
-          - {label: Thumbnail Only?, name: preview_only, widget: boolean, default: false, required: false}
-  - name: pages
-    label: "Pages"
-    files:
-      - file: "content/privacy.md"
-        label: "Privacy Policy"
-        name: "privacy"
-        fields:
-          - {label: "Title", name: "title", widget: "string"}
-          - {label: "Publish Date", name: "date", widget: "datetime"}
-          - {label: "Subtitle", name: "subtitle", widget: "string", required: false}
-          - {label: "Summary", name: "summary", widget: "markdown", required: false}
-          - label: "Draft"
-            name: "draft"
-            required: false
-            widget: "boolean"
-            default: false
-          - {label: "Body", name: "body", widget: "markdown"}
-      - file: "content/terms.md"
-        label: "Terms"
-        name: "terms"
-        fields:
-          - {label: "Title", name: "title", widget: "string"}
-          - {label: "Publish Date", name: "date", widget: "datetime"}
-          - {label: "Subtitle", name: "subtitle", widget: "string", required: false}
-          - {label: "Summary", name: "summary", widget: "markdown", required: false}
-          - label: "Draft"
-            name: "draft"
-            required: false
-            widget: "boolean"
-            default: false
-          - {label: "Body", name: "body", widget: "markdown"}
+{{- with partialCached "mod-wowchemy-cms/generate" . "mod-wowchemy-cms/generate" -}}
+  {{- . }}
+{{- end -}}