Replies: 2 comments
-
What an interesting use case! Shortcode processing is tightly coupled to the notion of a document (for example, document metadata is passed to the shortcode) so it's unlikely we could process shortcodes in metadata directly. That said, a good simple way to do this would be to swap out the document content with the metadata content, process the shortcode, and then swap them back. You wouldn't even need to "read" the document content since you can swap the content provider out and back so it'll be performant. From a quick LINQPad experiment to show it works: async Task Main()
{
Engine engine = new Engine();
engine.Shortcodes.Add<RawShortcode>();
engine.Pipelines.Add("Test").ProcessModules.AddRange(
// Create the test document with content of "Foo"
// and the metadata with shortcode in "Bar" metadata
new CreateDocuments("Foo"),
new SetMetadata("Bar", "abc <?# raw ?>bar<?#/ raw ?> xyz"),
// Copy the existing content provider to metadata so we can
// get it back later and then copy the metadata with shortcode to content
new SetMetadata("ExistingContentProvider", Config.FromDocument(doc => doc.ContentProvider)),
new SetContent(Config.FromDocument(doc => doc.GetString("Bar"))),
// Process the shortcodes in the content
new ProcessShortcodes(),
// Copy the processed content back to metadata and replace the content provider
new SetMetadata("Bar", Config.FromDocument(async doc => await doc.GetContentStringAsync())),
new SetContent(Config.FromDocument(doc => doc.Get<IContentProvider>("ExistingContentProvider"))));
await engine.ExecuteAsync();
// Validate results
IDocument output = engine.Outputs["Test"].First();
string content = await output.GetContentStringAsync();
string metadata = output.GetString("Bar");
content.Dump();
metadata.Dump();
} That results in:
You could even encapsulate this behavior in it's own module: public class ProcessMetadataShortcodes : ForAllDocuments
{
private readonly string _key;
public ProcessMetadataShortcodes(string key)
{
_key = key ?? throw new ArgumentNullException(nameof(key));
Children.Add(
new SetMetadata("ExistingContentProvider", Config.FromDocument(doc => doc.ContentProvider)),
new SetContent(Config.FromDocument(doc => doc.GetString(_key))),
new ProcessShortcodes(),
new SetMetadata(_key, Config.FromDocument(async doc => await doc.GetContentStringAsync())),
new SetContent(Config.FromDocument(doc => doc.Get<IContentProvider>("ExistingContentProvider"))));
}
} |
Beta Was this translation helpful? Give feedback.
-
Thanks Dave, I will give this a shot |
Beta Was this translation helpful? Give feedback.
-
We have a situation where we add metadata to a document that contains SEO related information (such as the document title and meta description).
We want these metadata fields to also contain shortcodes, but I cannot see a way to instruct the
ProcessShortcodes
module that it should process shortcodes in certain metadata fields. Looking at the source code, it appears that it is only looking for shortcodes in the document content.I was hoping that we can do something similar to the
RenderMarkdown
module that allows you to specify asourceKey
parameter to indicate whether the processing should be done on a specific metadata field rather than the document content.Is this by any chance something that is on your roadmap? If not, is there another way we could handle this at the moment?
Beta Was this translation helpful? Give feedback.
All reactions