fluid
fluid copied to clipboard
How to use dotnet core viewcomponents in fluid?
My apologies if this is simple to do but I have searched for the last few days now and I can't figure it out.
Usually in a Razor page one would have code to invoke a ViewComponent @await Component.InvokeAsync("Products") or as a tag helper
<vc:products parameter1="parameter1 value" parameter2="parameter2 value"> </vc:products>
edit* I think this can be done with custom tags but I am facing the same problem as in https://github.com/sebastienros/fluid/issues/176
Where and how does one add the dependencies?
The sample attached with the project shows a custom version that Fluid works with ASP.NET Core MVC, but not all the asp.net Core features is implemented to use Fluid
Thank you for your prompt response, I appreciate it.
I have looked at the samples given and although they were quite helpful they are not very advanced.
I have created a custom tag that sort of does what I want but I'd prefer having it use the caching functionality of the Rendering Engine of fluid.
The below is just a hack I smashed together late last night and does what I want(will need to change it to be more dynamic on retrieving the model data and view.
Is there a better way to get the fluid View Engine to incorporate similar functionality as dotnet core's view components?
namespace TemplatingPOC.FluidTags
{
public class ViewComponentTag : ExpressionTag
{
private IHttpContextAccessor _httpContext;
private IHostingEnvironment _hostingEnvironment;
internal HeaderTop GetHeaderTop() // TODO: Move this somewhere else
{
// TODO: Database.GeHeaderTop for current tenant
var headerTop = new HeaderTop
{
DefaultWelcomeMessage = $"Welcome to my website",
Items = new List<HeaderTopItem>()
};
headerTop.AddItem("Login", $"/account/login?tenant=tenant1");
return headerTop;
}
public override async ValueTask<Completion> WriteToAsync(TextWriter writer, TextEncoder encoder,
TemplateContext context, Expression expression)
{
//var scope = TemplateContext.GlobalScope;
//var container = scope.GetValue("Container").ToObjectValue() as IContainer;
//_httpContext = container.Resolve<IHttpContextAccessor>();
var model = GetHeaderTop();
var viewPath = (await expression.EvaluateAsync(context)).ToStringValue();
if (!viewPath.EndsWith(FluidViewEngine.ViewExtension, StringComparison.OrdinalIgnoreCase))
{
viewPath += FluidViewEngine.ViewExtension;
}
var currentViewPath = context.AmbientValues[FluidRendering.ViewPath] as string;
var currentDirectory = Path.GetDirectoryName(currentViewPath);
var viewComponent = Path.Combine(currentDirectory, viewPath);
var fileProvider = context.AmbientValues["FileProvider"];
var fileInfo = (fileProvider as IFileProvider).GetFileInfo(viewComponent);
context.Model = model;
context.LocalScope.SetValue("Model", model);
using (var stream = fileInfo.CreateReadStream())
{
using (var sr = new StreamReader(stream))
{
var ss = sr.ReadToEnd();
if (FluidViewTemplate.TryParse(ss, out var template, out var errors))
{
await template.RenderAsync(writer, encoder, context);
}
else
{
throw new Exception(string.Join(Environment.NewLine, errors));
}
}
}
return Completion.Normal;
}
}
}
And the view(Header.liquid)
<div class="header-top">
<div class="container">
<div class="header-right">
<p class="welcome-msg">{{Model.defaultWelcomeMessage}}</p>
<div class="header-dropdown dropdown-expanded">
<a href="#">Links</a>
<div class="header-menu">
<ul>
{% for item in Model.items %}
<li><a href="{{item.link}}">{{item.displayText | prettyprint}}</a></li>
{% endfor %}
</ul>
</div>
</div>
</div>
</div>
</div>
Is there a better way to get the fluid View Engine to incorporate similar functionality as dotnet core's view components?
If I'm not the wrong the sample provided in the repo is a show case of how Fluid can be used from withing AspNetCore, but may be @sebastienros has some feedback about what you asking for
I assume the MVC View Engine could be extended with such tag. And probably also handle Tag Helpers (note Tag Helpers is already implemented in Orchard Core so that might be a good start)