caddy -version)?8.3, But it doesn't matter. It's the same in 8.2 also.
Access an object in markdown front matter:
In template:
<p>{{ .Doc.someobject.somefield }}</p>
In front matter (TOML, but the same in all front matter):
+++
title = "sometitle"
[someobject]
somefield = "somevalue"
+++
Run on mac osx, with just caddy
On the page, <p>somevalue</p>
Nothing at all, no error, and nothing on the page. Inspecting the page reveals an element <no value> put in place instead of the actual value.
Create a Caddyfile with a markdown directive, the options don't matter, just make it so that it will read files in the markdown directory as markdown files and the file template.html as the default template.
Create a directory markdown and create a markdown file in the directory, call it index.md.
Put the following in the file index.md:
+++
key = "value"
[object]
objkey = "objvalue"
+++
Page
Create the file template.html and put the following in it:
<!doctype html>
<html lang="en">
<head>
<title>Title</title>
</head>
<body>
Key: {{ .Doc.key }}
Objkey: {{ .Doc.object.objkey }}
</body>
</html>
Now, start caddy and go to
You will see:
Key: value
Objkey:
The desired result is:
Key: value
Objkey: objvalue
Sorry, front matter does not support objects.
Thanks.
I could probably clarify that in the documentation.
Why are objects needed in your case, just curious?
Mostly for keeping it clean, and some other things. I like having sections, and I use them in templates for various things. (Most other markdown servers with front matter support them.)
Thanks anyways though. I think I've figured out how to add it in to my own local build of caddy anyways.
@MrH100000 Is it complicated? We could take another look. Mostly we were trying to avoid complexity.
My solution was the use of interfaces, it wasn't very complicated.
You can either add another variable alongside Flags, and Variables in metadata.go and in process.go, so you could use it like {{ .DocObjects.<someobject> }} or whatever you want to call it and then set a default: in metadata.load in the parsedMap for loop. Ex: (Around line 50 in markdown.go)
// store everything as a variable
for key, val := range parsedMap {
switch v := val.(type) {
case string:
m.Variables[key] = v
case bool:
m.Flags[key] = v
default:
m.<NameOfSomeInterfaceMap>[key] = v
}
}
Or you can just change Variables (in markdown.go) and Doc (in process.go) to map[string]interface{} and then around line 190 in process.go change []byte(title) to []byte(title.(string)) and then {{ .Doc.<someobject> will just work. Ex: (Around line 50 in markdown.go)
// store everything as a variable
// Markdown.go, line ~50
for key, val := range parsedMap {
switch v := val.(type) {
case string:
m.Variables[key] = v
case bool:
m.Flags[key] = v
default:
m.Variables[key] = v
}
}
Take look at https://github.com/mholt/caddy/compare/master...MrH100000:master.
That looks fine.
If you are willing to contribute that, add/edit a test case or two to include objects for json, toml, yaml. We'll be glad to merge it :)
Okay, I'll do that now.
So it all works fine except for the JSON, because JSON objects use { and }. so the metadata parser thinks that the } is the end of the front matter, not the object. So do you want to just not support JSON objects, or change the beginning/ending tags for JSON? (You could just make the beginning and ending {{ and }}, and drop the 2nd { or } when parsing it)
Can you just surround the JSON bytes with { and } before you unmarshal?
Hmm. Let me check.
I don't think so.
Go ahead and open a pull request anyway, we'll take a look.
Ok, I will.
Looking at other repo's of projects that try and use JSON front matter, I think it would be best to just change the start and end tags to something like {{{ or {{
I have a change to the markdown middleware that fixes the parsing of the JSON front-matter in such a manner that actually parses things until all "{" and "}" are parsed.
Maybe @MrH100000 should hold on till @weingart's PR (https://github.com/mholt/caddy/pull/762) is merged, to avoid possible conflicts.