-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to render a shape without a theme #5687
Comments
Apparently we are missing it. You can still render something without a theme manually in the meantime:
|
BuildDisplay uses theme layout to inject zones defined in shape. |
Was this implemented in 1.0? |
/cc @netwavebe Also wondering what it would mean to not use any theme, since shapes can only render things into zones. {
"content": "<p>Hello</p>",
"footer": "<script>...</script>",
"meta": "<link .../>"
} Even if you just want the content zone, |
Makes sense to be able to retrieve every rendered shape individually if you are doing a headless website. I remember getting a request for this by the guys from Air Whistle Media. Generally, when you create a headless website you don't want to retrieve the entire rendered page but only some parts. In this case, you want to use the |
@sebastienros I agree there are complex scenario's, but that's not always the case. In Orchard Dashboard I have a liquid template that renders the summary of a product (Design > Templates > I've used this to render some featured products on the homepage, works perfect. Now I want to use this template in Angular (like @Skrypt's example). I have an API controller that gets a list of products. I can do two things there:
I did the first option on https://t-shirtskempen.be/bestellen. This has several downsides: there's a lot a databinding going on in Angular, you would need to maintain two version of the same 'view', etc... So for a new project I was looking at option two, but there seems to be no way to achieve this currently? |
@netwavebe Have you tried with creating |
This should work but I think he wants to still have a Layout for the "Full CMS" website. So, we need an option to remove the Layout explicitly when rendering the shape with the GraphQL endpoint. |
@netwavebe I haven't fully followed the issue, but Seb said you were concerned about the site layout? You can inject the layout accessor in your api controller, and add an alternate to it, alternate would be an different layout (largley empty) |
Maybe some ideas around the LayoutAccessor to allow this scenario, like disabling, or setting a custom one. |
@deanmarcussen Could you share some code on how to add an alternate with a different layout? |
It's theme selector that implements |
Sure remind me tomorrow on gitter. Also useful is a PartialViewResult. I use that to dynamically fetch and then compile as vue components sometimes |
I think it would be fair to have some generic method to support that instead of requiring to create custom API endpoints. |
It's not a problem If using controller View - as you can set Layout or ThemeLayout or |
Theme can be removed by Creating filter something like below public class NoThemeFilter : IAsyncViewActionFilter
{
public Task OnActionExecutionAsync(ActionContext context)
{
var razorViewFeature = context.HttpContext.Features.Get<RazorViewFeature>();
// Add your filter condition here
if (razorViewFeature?.Theme != null)
{
razorViewFeature.Theme = null;
}
return Task.CompletedTask;
}
} and in startup services.AddScoped<IAsyncViewActionFilter, NoThemeFilter>(); Notice that we are not adding the filter to |
@ns8482e I registered your example in startup without a filter condition, so I would expect theming to be gone everywhere but that's not the case. Breakpoints in |
it should be called by DisplayManagement - when you render a shape OrchardCore/src/OrchardCore/OrchardCore.DisplayManagement/Razor/RazorShapeTemplateViewEngine.cs Lines 157 to 162 in 339d74b
|
and for liquid - it's called from here OrchardCore/src/OrchardCore/OrchardCore.DisplayManagement.Liquid/LiquidViewTemplate.cs Lines 215 to 222 in 339d74b
|
@netwavebe try adding I guess you still need to use Theme to identify which shape binding to render, so don't set theme to null, instead set ThemeLayout to null as suggested by @sebastienros if (razorViewFeature?.ThemeLayout != null)
{
razorViewFeature.ThemeLayout = null;
} |
Mmmm, it seems it's working correctly IF there is a custom template... Here's what I did/tried... This is a part of my code: public async Task<IEnumerable<string>> RenderProducts(IEnumerable<ContentItem> products)
{
var renderedProducts = new List<string>();
foreach (var product in products)
{
var productShape = await _contentItemDisplayManager.BuildDisplayAsync(product, _updateModelAccessor.ModelUpdater, "Summary");
var renderedProduct = await _displayHelper.ShapeExecuteAsync(productShape);
using (var stringBuilder = StringBuilderPool.GetInstance())
{
using (var stringWriter = new StringWriter(stringBuilder.Builder))
{
renderedProduct.WriteTo(stringWriter, HtmlEncoder.Default);
await stringWriter.FlushAsync();
renderedProducts.Add(stringWriter.ToString());
}
}
}
return renderedProducts;
} I'm calling this method in an API controller with a bunch of product content items. The result is send in JSON to an Angular client. This is what Angular receives: First = "Summary" view of a product, embedded in the theme This changes when creating a custom template: This is what Angular receives with the above template in place: This is exactly what I want. I'm not sure why this happens? Why does it render theming for the "default" template, but not for my custom template? Not that I'm complaining... 😉 |
I assume the default template is a Razor file? |
yes - |
but would it mean that if the Blog theme for instance was built in Razor, and we were to render the list of Blog Posts with Summary, then it would render the layout for each? That seems odd. I will have to debug it to understand how it works again. |
You are correct, I was testing in blog theme |
@sebastienros @ns8482e Almost, it will not render the theme for each, only for the first. I tried this in my project: removed the liquid template and placed a view When I rename the view to So cshtml or liquid makes no difference. But when I create a template in the UI (Design > Templates), I get this: For the record, I'm running on OC 1.0. |
@dpomt Create a template via the admin dashboard and it will work correctly. |
It seems to me that the questions were discussed. If there are concrete improvement suggestions, please open issues for them. |
I'm trying to render a shape in a controller action without the website theme. In orchard 1, there was a Theme attribute that did this. Is there a way in core?
The text was updated successfully, but these errors were encountered: