Don't ask me why -- well, ok, ask me and I'll tell you -- but I have been investigating lately how to create my own Engine instance (i.e. Tridion.ContentManager.Templating.Engine). Engine is an abstract class and as such cannot be instantiated directly. Time to get decompily...
I figured out there are a couple of implementations for Engine, but question is when is one used over the other. The simple solution was to log somehow the engine.GetType() method call in different contexts and see what comes back.
I ended up with a very simple C# Fragment:
package.PushItem("TYPE",
package.CreateStringItem(ContentType.Text, engine.GetType()));
And its DWT counterpart:
Engine type: @@TYPE@@
The result is the following:
If you notice, engine is in fact initialized when the Render method is executed. Weirdly, Render is a method defined by IRenderer. That is pretty weird! TemplateRenderer extends/implements both Engine and IRenderer.
The code above will in fact start the publishing of the given Page with the given Page Template. That's a bit too much from what I was intending to do in the first place.
My goal is to simply have an Engine object so that I can instantiate a Package object. It seems like the following code is enough:
This will create a new item in the Package, so I can now use the object locally without having to perform an actual publish or preview in Template Builder.
What a hack!
I figured out there are a couple of implementations for Engine, but question is when is one used over the other. The simple solution was to log somehow the engine.GetType() method call in different contexts and see what comes back.
I ended up with a very simple C# Fragment:
package.PushItem("TYPE",
package.CreateStringItem(ContentType.Text, engine.GetType()));
And its DWT counterpart:
Engine type: @@TYPE@@
The result is the following:
- executing the template in Template Builder displays: Tridion.ContentManager.Templating.Debugging.DebuggingEngine
- executing in CME Preview or doing an actual publish displays : Tridion.ContentManager.Templating.TemplatingRenderer
Session session = new
Session();
Page page = new
Page(new TcmUri("tcm:20-102-64"),
session);
Template template = new
PageTemplate(new
TcmUri("tcm:20-715-128"),
session);
ResolvedItem resolvedItem = new
ResolvedItem(page, template);
PublishInstruction publishInstruction = new PublishInstruction(session);
PublicationTarget publicationTarget = new PublicationTarget(new TcmUri("tcm:0-1-65537"), session);
RenderInstruction renderInstruction = new RenderInstruction(session)
{ RenderMode = Tridion.ContentManager.Publishing.RenderMode.PreviewDynamic
};
RenderedItem renderedItem = new
RenderedItem(resolvedItem,
renderInstruction);
RenderContext renderContext = new
RenderContext();
IRenderer engine = new
TemplatingRenderer();
engine.Render(resolvedItem,
publishInstruction, publicationTarget, renderedItem, renderContext);
If you notice, engine is in fact initialized when the Render method is executed. Weirdly, Render is a method defined by IRenderer. That is pretty weird! TemplateRenderer extends/implements both Engine and IRenderer.
The code above will in fact start the publishing of the given Page with the given Page Template. That's a bit too much from what I was intending to do in the first place.
My goal is to simply have an Engine object so that I can instantiate a Package object. It seems like the following code is enough:
Engine engine = new
TemplatingRenderer();
Package package = new
Package(engine);
// test it
package.PushItem("name", package.CreateHtmlItem("value"));
What a hack!
Comments
For long, I wanted to play with it in my Java Mediator quickly, without having to go load the TBB in Template Builder, execute it, stop TB because it locked all my JARs/DLLs, etc.
However, I also see a strong use-case for unit testing your templates! A continuous build environment (CM side). This can be fine grained (even at TBB level). Kinda: if that's the input package, that's the output. Is it the expected one?
Pretty cool :)