estruyf / vscode-front-matter

Front Matter is a CMS running straight in Visual Studio Code. Can be used with static site generators like Hugo, Jekyll, Hexo, NextJs, Gatsby, and many more...
https://frontmatter.codes
MIT License
1.99k stars 83 forks source link

Issue: New content type template does not preserve frontmatter formatting/comments #384

Closed anakinsleftleg closed 2 years ago

anakinsleftleg commented 2 years ago

Describe the bug When creating a new content based on a content type with a template as from Issue #351 any frontmatter formatting in the template file is wiped out. Comments are removed, whitespace is removed. Keys which exist in the template but not in the content type are preserved and any non-frontmatter content (below the frontmatter) is preserved.

To Reproduce Steps to reproduce the behavior:

  1. Make a file like: /archetypes/blog/index.md/
    
    ---
    # Predefined Parameters (eg: .Title)
    title: {{ replace (replaceRE `^\d*(-| |)` "" .Name) "-" " " | title }}
    slug: {{ replaceRE `^\d*(-| |)` "" .Name | urlize }}
    draft: true
    date: {{ .Date }}
    lastmod: {{ .Date }}
    description: &summary 
    summary: *summary
    keywords: 
    type: blog
    weight: 10
    randokey: nothin
    # User-Defined Parameters (eg: .Params.categories)
    subtitle: 
    featuredPost: false
    headerImage:
    src: images/headerdefault.png
    title: 
    alt: 
    categories: 
    tags: 
    ---

This is a test.


2. Add it to the content type:
```json
"name": "blog",
"pageBundle": true,
"template": "[[workspace]]/archetypes/blog/index.md",
  1. Create a new content of type blog
  2. See what it hath wrought:
    
    ---
    title: test1
    slug: ""
    draft: ""
    date: 2022-08-09T23:43:44.433Z
    lastmod: 2022-08-09T23:43:44.433Z
    description: "&summary"
    summary: "*summary"
    keywords: ""
    type: blog
    weight: 10
    randokey: nothin
    subtitle: ""
    featuredPost: false
    headerImage:
    src: images/headerdefault.png
    title: test1
    alt: ""
    categories: ""
    tags: ""
    ---

This is a test.



**Expected behavior**
Formatting to remain, only the keys defined in the content type would have their values specifically changed.

**Desktop (please complete the following information):**
 - OS: Windows 10
 - VSCode 1.7.0
 - Front Matter 8.0.1

**Additional context**
Also, in Hugo at least, one can define an archetype for a page bundle, with folders and extra files and all. They will all get created when the new content of that archetype is created. It would be nice to have the same behavior with content types linked to templates.
anakinsleftleg commented 2 years ago

I also just noticed that I have two keys that are called title but one is for the content title at the top and one is a child of the headerImage key. In the template the child title is empty, but after creation in FM, it gets populated with the page title also.


Also, even in the content type I define the default values for the keys with the reference variable, it treats them like strings:

        {
          "title": "Description",
          "name": "description",
          "type": "string",
          "default": "&summary"
        },
        {
          "title": "Summary",
          "name": "summary",
          "type": "string",
          "default": "*summary"
        },

becomes

description: "&summary"
summary: "*summary"

when I want

description: &summary
summary: *summary

And the datetime fields are made with UTC time, not local time.

estruyf commented 2 years ago

Comments are not preserved

Comments are by default removed by the YAML parser. We already had this question or suggestion a while ago, but unfortunately, there is no easy fix for this apart from rewriting parts of the YAML parser.

Formatting changes

The YAML parser converts strings to valid YAML if it contains special characters.

From the YAML docs: Strings containing any of the following characters must be quoted. :, {, }, [, ], ,, &, *, #, ?, |, -, <, >, =, !, %, @, `

Besides the two double quotes added, it is still a valid string that your SSG can use.

HeaderImage title

Could you share your Content Type configuration for this? That way, we can test it out.

anakinsleftleg commented 2 years ago

Could you share your Content Type configuration for this? That way, we can test it out.

{
  "$schema": "https://frontmatter.codes/frontmatter.schema.json",
  "frontMatter.taxonomy.contentTypes": [
    {
      "name": "blog",
      "pageBundle": true,
      "template": "[[workspace]]/archetypes/blog/index.md",
      "previewPath": null,
      "fields": [
        {
          "title": "Post Title",
          "name": "title",
          "type": "string",
          "single": true,
          "default": "{{title}}"
        },
        {
          "title": "Slug",
          "name": "slug",
          "type": "slug",
          "editable": true,
          "default": "{{slug}}"
        },
        {
          "title": "Is In Draft?",
          "name": "draft",
          "type": "draft",
          "default": true
        },
        {
          "title": "Created On",
          "name": "date",
          "type": "datetime",
          "isPublishDate": true,
          "default": "{{now}}"
        },
        {
          "title": "Last Modified On",
          "name": "lastmod",
          "type": "datetime",
          "isModifiedDate": true,
          "default": "{{now}}"
        },
        {
          "title": "SEO Description",
          "name": "description",
          "type": "string",
          "default": "&summary"
        },
        {
          "title": "Link Preview Summary",
          "name": "summary",
          "type": "string",
          "default": "*summary"
        },
        {
          "title": "Target Keywords",
          "name": "keywords",
          "type": "list"
        },
        {
          "title": "Content Type",
          "name": "type",
          "type": "string",
          "default": "blog",
          "hidden": true
        },
        {
          "title": "Weight",
          "name": "weight",
          "type": "number",
          "default": 10
        },
        {
          "title": "Sub-Title",
          "name": "subtitle",
          "type": "string",
          "single": false,
          "wysiwyg": true,
          "default": ""
        },
        {
          "title": "Is A Featured Post?",
          "name": "featuredPost",
          "type": "boolean",
          "default": false
        },
        {
          "title": "Header Image",
          "name": "headerImage",
          "type": "fields",
          "fields": [
            {
              "title": "Image",
              "name": "src",
              "type": "image",
              "default": "images/headerdefault.png",
              "isPreviewImage": true
            },
            {
              "title": "Image Title",
              "name": "title",
              "type": "string",
              "single": true,
              "default": ""
            },
            {
              "title": "Image Alt-Text",
              "name": "alt",
              "type": "string",
              "single": true,
              "default": ""
            }
          ]
        },
        {
          "title": "Categories",
          "name": "categories",
          "type": "categories"
        },
        {
          "title": "Tags",
          "name": "tags",
          "type": "tags"
        }
      ]
    }
  ],
  "frontMatter.framework.id": "hugo",
  "frontMatter.content.publicFolder": "assets",
  "frontMatter.content.pageFolders": [
    {
      "title": "Pages",
      "path": "[[workspace]]/content",
      "excludeSubdir": true
    },
    {
      "title": "Blog",
      "path": "[[workspace]]/content/blog"
    },
    {
      "title": "About Page",
      "path": "[[workspace]]/content/about"
    }
  ],
  "frontMatter.dashboard.content.cardTags": "tags"
}

If I change the default value for the headerImage child title field, to something like " " or anything else, it inserts that default value, not the page title. But it shouldn't be inserting the page title anyway even with a default empty string.

Regarding the &summary / *summary variables, is there no way to preserve them? I admit this is more something for a dev to use, less of a user interacting with a CMS. And a user that only interacted with the CMS wouldn't care or notice.

estruyf commented 2 years ago

The title field is indeed a bug that will get fixed.

Unfortunately, the summary variables you add cannot be fixed, as it would invalidate the YAML parser.

anakinsleftleg commented 2 years ago

Ok, Thank you. I understand about the YAML parser. I'll have to decide how I want to work with it or not. Thank you for the fix and the clarity.