YAML frontmatter curiosities in the Wiki
GitLab's Wiki has some interesting behaviour regarding frontmatter, and we might want to clean up some of it if we want to depend on it more in the future: 1. The web UI serialises the frontend state's frontmatter object into YAML and tacks it onto the start of the user content, sending it as one big string. The REST API, on the other hand, accepts `front_matter` as a separate structured hash, which then gets serialised on the backend. We should normalise these, most likely in the direction of making the web UI act more like the API here so we don't duplicate work. The frontmatter is stored internally in this way (prepended onto the front of the user document, including any _user_ frontmatter), but we kind of half treat it as an abstraction and hide it away from the frontend, and half don't. 2. We have an awkward regex-based manual parser for frontmatter, and it's become [quite hard to read](https://gitlab.com/gitlab-org/gitlab/-/blob/4bf6cc4a201c1db67319b4cdb6a6a67e1fa34080/lib/gitlab/front_matter.rb). I don't trust it, and given the amount of `UNTRUSTED` I suppose _we_ don't either. The `# Original pattern:` comment only invites more questions without answering them itself. I think we should replace this with a small well-defined state machine instead of this, and we can do so safely with a good bank of unit tests. 3. We silently error on TOML/JSON frontmatter (`lib/gitlab/wiki_pages/front_matter_parser.rb:75`), so if you push a document with TOML/JSON frontmatter to the Wiki git repository, it'll just sit in the body content, and cannot be used for the "system" frontmatter. The first frontmatter is the system's **if and only if** it's YAML, otherwise it's the user's. Any secondary frontmatter is also the user's. This is kind of confusing, but the whole situation is when you consider people accessing the Wiki git repository directly. 4. `Psych::DisallowedClass` is also treated as an error, so if a user edits the "system" frontmatter to contain e.g. a date without double-quotes forcing it to be a string, this will cause it to just get shown in the page body instead. 5. The API allows any key in the `front_matter` hash, but the schema only declares `title` (`lib/api/wikis.rb:102`). We will save anything, though.
issue