Closed daveaglick closed 2 years ago
To that end I wonder if it's possible to generalize this and look for ---
at the end of the first line of a file and at the start of a following line (with the reverse of the first line extra characters?).
So it turns out changing the module to accept two different styles of delimiters ("normal" and the proposed comment style) is going to be tricky. It would also be nice to support multiple delimiter sets in a single module so as more kinds of delimiters are supported we don't have to continue parsing the file into a string array each time. Being able to pass in front matter delimiter data as a single string would be nice too so we can add a setting to describe additional front matter delimiters.
I think the answer to all these is to support RegEx for specifying how to find front matter. That leaves a question of what to do about existing code. Should the current way of specifying also be accepted (and maybe converted to a RegEx)?
This is now done and will go out with the next Statiq Web release, which will allow syntax like what's in the description of this issue for defining front matter in Razor files (in addition to HTML comment syntax like <!---
as well).
In Statiq Framework front matter is extracted by the ExtractFrontMatter
module which now accepts regular expressions. When using the ExtractFrontMatter
module in Statiq Framework without predefined front matter handling like Statiq Web provides, the following regular expressing can be used for Razor block comment front matter: \A(?:^\r*@\*-+[^\S\n]*$\r?\n)(.*?)(?:^\r*-+\*@[^\S\n]*$\r?\n)
.
I'm trying to use this feature and I'm not sure it's working properly for me.
I have my project configured to use Statiq.Web 1.0.0-beta.47, so I think that should have the code for this to work already.
In the head of base.cshtml
I have
@if(Document.GetBool("HighlightCode", false))
{
<link rel="stylesheet" href="highlight/styles/vs2015.min.css">
<script src="highlight/highlight.min.js" onload="hljs.highlightAll();"></script>
}
And then in post.cshtml
I start the file with
@*---
HighlightCode: true
---*@
But that doesn't seem to include the contents of the @if
. Am I doing something wrong?
Edit: looking more into the original discussion, this might be because I'm trying to use it in a template, whereas the original discussion was talking specifically about final pages containing the frontmatter.
Edit2: Okay, I sorted it out with the ViewData
dictionary. It becomes a bit more complex than I hoped but it will have to do
@if((ViewData.ContainsKey("HighlightCode") && (bool)ViewData["HighlightCode"]) || Document.GetBool("HighlightCode", false))
What's the relationship between base.cshtml
and post.cshtml
? If base.html
is a Razor layout, then the document metadata should still be available through the Document
page property just like the actual page.
Both are layouts.
A post will have Layout: @"_layouts/post.cshtml"
, whereas in the post.cshtml
file I have
@{
Layout = @"_layouts/base.cshtml";
}
Interesting - as far as I can tell, that should still work. Here's a little example I worked up...
input/_OuterLayout.cshtml
<html>
<head>
</head>
<body>
<div>Outer layout color: @Document.GetString("Color")</div>
@RenderBody()
</body>
</html>
input/_InnerLayout.cshtml
:
@{
Layout = @"/_OuterLayout.cshtml";
}
<div>Inner layout color: @Document.GetString("Color")</div>
@RenderBody()
input/Test.cshtml
:
@*---
Color: Blue
---*@
@{
Layout = @"/_InnerLayout.cshtml";
}
<div>Test color: @Document.GetString("Color")</div>
Output:
<html>
<head>
</head>
<body>
<div>Outer layout color: Blue</div>
<div>Inner layout color: Blue</div>
<div>Test color: Blue</div>
</body>
</html>
Have I correctly replicated your scenario, or did I miss something?
Almost, but I was trying to set the frontmatter from the template, which I think is what's not supported in this manner.
input/_OuterLayout.cshtml
<body>
<div>Outer layout color: @Document.GetString("Color")</div>
@RenderBody()
</body>
input/_InnerLayout.cshtml
:
@*---
Color: Blue
---*@
@{
Layout = @"/_OuterLayout.cshtml";
}
<div>Inner layout color: @Document.GetString("Color")</div>
@RenderBody()
input/Test.cshtml
:
@{
Layout = @"/_InnerLayout.cshtml";
}
<div>Test color: @Document.GetString("Color")</div>
Expected output:
<body>
<div>Outer layout color: Blue</div>
<div>Inner layout color: Blue</div>
<div>Test color: Blue</div>
</body>
I was trying to set the frontmatter from the template, which I think is what's not supported in this manner
Ah, yes - you're exactly right. The layout files don't get processed in the same way so they can't set front matter (there's not even a Statiq document for them, they become "part" of the contained page during rendering).
Glad you figured out an approach that will (mostly) work though!
See https://github.com/statiqdev/Discussions/discussions/132
Note that the syntax should clearly indicate front matter over other top-of-file block comments. I.e.
As part of this change, since we're establishing a pattern, the script front matter comment support should be changed to require a similar dash style delimiter.