[PAGES-1153] Component Inheritance with Visual SPA Editor Created: 18/Aug/20  Updated: 14/Jun/23  Resolved: 19/May/23

Status: Closed
Project: Magnolia pages module
Component/s: None
Affects Version/s: None
Fix Version/s: 6.3.0, 6.2.28

Type: Story Priority: Major
Reporter: Christopher Zimmermann Assignee: Oanh Thai Hoang
Resolution: Fixed Votes: 7
Labels: None
Σ Remaining Estimate: Not Specified Remaining Estimate: Not Specified
Σ Time Spent: 7d 1.5h Time Spent: 5d 3.5h
Σ Original Estimate: Not Specified Original Estimate: Not Specified

Issue Links:
Problem/Incident
causes PAGES-416 DOC: Indicate when page templating fe... Open
Relates
relates to PAGES-1162 DOC: Component autogeneration and inh... Closed
relates to PAGES-1128 Component Autogeneration should work ... Closed
relates to MGNLREST-732 Tune default configuration of jcrPage... Closed
dependency
depends upon MGNLREST-684 Support annotation for DeliveryEndpo... Closed
relation
is related to MGNLPN-474 Get (stateless) personalized content ... Closed
Sub-Tasks:
Key
Summary
Type
Status
Assignee
PAGES-1154 Implement Sub-task Completed Oanh Thai Hoang  
PAGES-1155 Review Sub-task Completed Javier Benito  
PAGES-1156 piQA Sub-task Completed Javier Benito  
PAGES-1157 QA Sub-task Completed Phong Le Quoc  
Template:
Acceptance criteria:
Empty
Task DoD:
[X]* Doc/release notes changes? Comment present?
[X]* Downstream builds green?
[X]* Solution information and context easily available?
[X]* Tests
[X]* FixVersion filled and not yet released
[ ]  Architecture Decision Record (ADR)
Release notes required:
Yes
Documentation update required:
Yes
Date of First Response:
Epic Link: SPA Editor Backlog
Sprint: DevX 37, DevX 38
Story Points: 5
Team: DeveloperX
Work Started:
Approved:
Yes

 Description   

As a developer I want to use magnolias 'Component Inheritance' feature when I use the Visual SPA Editor (SPA Renderer and frontend frameworks and REST endpoints) so that I can provide a very comfortable author experience for things like footers, headers and sidebars.

Acceptance Criteria

  • When component inheritance is specified in the templates, then developers can also use this in front-end projects. They have some convenient way to get the inherited contents on sub-pages. Maybe the REST endpoint simply delivers the inherited content directly as if the inherited components were simply on the subpages.

Context

Component Inheritance is a popular feature in Magnolia templating. It allows authors to configure componets on a top page, and then all of the subpages automatically get that same configuration.

It is typically used for things like headers, footers and "extra" or "sidebar" content.

There are workarounds, such as managing that content to be shared across multiple pages in its own unique page, or in a separate app. But the authoring experience is not as good, its more complicated. It would be better to enable this useful features for SPA as well as freemarker templating.

https://docs.magnolia-cms.com/product-docs/6.2/Templating/Template-definition/Area-definition/Component-inheritance.html

Workaround

Use inheritance without rest inheritance in SPA:
https://github.com/bartoszstaryga/mgnl-spa-inheritance

For Discovery phase:

  • Estimation for amount of time to implement.
  • Investigate possible approaches. 


 Comments   
Comment by Simon Tourville [ 21/Aug/20 ]

This issue is at least present in version 6.2.

Comment by Marc Johnen [ 08/Jan/21 ]

Is there a time frame for this? I wouldn't have expected this to be missing in the initial release.

Comment by Christopher Zimmermann [ 11/Jan/21 ]

No concrete timeframe yet.

Comment by Marc Johnen [ 11/Jan/21 ]

My current solution is to hardcode this in the page.js

  //get header from homepage
  const headerRes = await fetch(baseUrl + homePage);
  let header = await headerRes.json();
  header = header["header"];
  //add it to current page
  page["header"] = header;

As we are using a Next server, a second request per page is ok.

 

Comment by Simon Tourville [ 14/Jan/21 ]

Interesting solution but the requires an extra HTTP request which we would be happy to get rid of, ideally.

Comment by Bartosz Staryga [ 25/Mar/21 ]

slutz any update/eta for adding inheritance to Delivery Endpoints? We get questions on regular basis regarding this

Comment by Christopher Zimmermann [ 31/Mar/21 ]

Marking as related to MGNLPN-474 as they both have to do with making the delivery REST response more similar to what is rendered by the page editor in FTL rendering.

Comment by Bartosz Staryga [ 29/Nov/21 ]

Workaround to use inheritance without rest inheritance in SPA:
https://github.com/bartoszstaryga/mgnl-spa-inheritance

Comment by Mykola [ 17/Feb/22 ]

worth noticing, that inheritance not always is enabled at the root page level, it can be any nested page
so the real fix would be recurent function, that checks every parents inheritance.enabled field and if true, then return content of that area
and it needs to be implemented by the REST module rather then client side editor plugins

Comment by Mykola [ 17/Feb/22 ]

maybe some kind of a resolver (like AssetReferenceResolverDefinition) would work? 

Comment by Canh Nguyen [ 18/Apr/23 ]

The Delivery Endpoint is designed to serve data generally for pages and other content types. It's not working like a rendering engine that mixes content and template definitions.

There are some solutions could be implemented to support this feature:

  • Develop components that manage their owned data like the Navigation components in frontend-helpers's samples . No changes on the delivery endpoint.
  • Create a area/component reference resolver and support adding links to other page's areas/components. The delivery endpoint will resolve references and returns data from other pages.
  • Implement a new specific delivery endpoint implementation for pages or other pages like content types to generate data from content and template definitions. Another idea is not relevant to this feature, but I want to mention is that we could also return template annotations corresponding to each area/component from the content with this approach.
Comment by Christopher Zimmermann [ 18/Apr/23 ]

Based on internal discussion, lets go with 3rd proposed solution:
"Implement a new specific delivery endpoint implementation for pages or other pages like content types to generate data from content and template definitions". 
Please continue to discover this approach, or let me know if you need more input.

 

Re: "return template annotations corresponding to each area/component "
Lets consider that later, but yes good idea.
Tracking as https://jira.magnolia-cms.com/browse/MGNLREST-625

Comment by Marc Johnen [ 18/Apr/23 ]

As I understand, you want tie the generation of JSON to pages and components similar to
how working with FTLs? If this is so, I would be very happy. It could make magnolia headless
into a system developers want to work with again.

Excuse my honest opinion: the current headless implementation has a bad architecture and is
an absolute pain to work with. I always end up extending the JcrDeliveryEndpoint. There is
no way to implement business logic in headless. (I know you advocate to do this in the FE,
but this is bad design.)
Many of the problems would be solved if the generation of JSON would be done by the pages, components and
areas like it is when rendering FTLs using TemplateModels and ComponentModels (those were the classes?).
This would enable a much cleaner structure. It would be a dream to have the node in a model to implement some
business logic that you can pass on to the delivery endpoint.
The current design of iterating through nodes and then changing the output based on resolvers mapped
to properties is very bad. Iterating through the components and letting the pages and components alter the JSON
output would be much cleaner and solve most of the problems I'm facing on a daily basis.

This is a list of the most frequent issues I face using headless:

  • resolvers are only attached to a property name, it would be better if one could further restrict this, e.g. to comonents.
    Again and again it happens, that someone defines a property in a component with the same name where a resolver
    it already attached to. Often times one notices too late. What do you do if you have two components using the
    same property name and later on you want to change how the property is being resolved only for one of these
    components? You will have to rename all properties in the jcr that already have been edited.
    I've been thinking already of always adding the component name to all property names. I will
    end up with an even longer list of resolver mappings.
  • resolvers should have the node of where the property value comes from in the context, otherwise it is not
    possible to implement any business logic
  • there is no way to append data to a node, e.g. if you want to just add a breadcrumb to a page or component
    (this is already impossible because in a resolver you don't have the node in the context)
  • the new depthInReferencedNode is great, it would be even better if you could also filter by node-type in the jcrReferenceResolver
  • I can't work with the current restrictions so I always extend the JcrDeliveryEndpoint myself, which is difficult since most methods are private, I end up copying the JcrDeliveryEndpoint
  • MessageBodyWriters are basically not extendable, e.g. AssetWriter only writes statically defined properties, you can't add your own properties. I frequently need this e.g. when adding properties to assets app
  • for headless there is no consistent method to generate i18n links
  • there is no mechanism to edit multi language urls  
  • ReferenceResolvers don't consider i18n / current locale

I'm sorry for all this negativity, but magnolia headless is in dire need improvement.
I hope my criticism can be at least a bit helpful for that.

Comment by Mykola [ 18/Apr/23 ]

I believe that there is a reasoning behind that choice, but still.. my first reaction is that yet another endpoint would bloat SPA side... but maybe I'm wrong. We even didn't have any proof-of-concept on this stage. Maybe it won't be a problem.

I hope it would not be a separate endpoints like /.rest/delivery/pages for regular content and /.rest/pagesWithInheritance with inheritance
because it would lead to runtime switching between those two
and it would be yet another problem to solve by developers, not a proposed solution, that this product was meant to solve.

Comment by Mykola [ 18/Apr/23 ]

@marc.johnen I'm also experience some of difficulties mentioned by you
I think part of it could be a separate issues here on Jira

  • resolvers are only attached to a property name: maybe saving resolver id as a system property would help. But I feel that this might be more costly performance wise.
  • resolvers should have the node of where the property value comes from: could you expand on this? (maybe a separate issue)
  • there is no way to append data to a node, e.g. if you want to just add a breadcrumb to a page or component: not sure what do you mean by appending data to a node, but we solve breadcrumbs in out project by using node path, which is always present
  • I always extend the JcrDeliveryEndpoint myself: did you tried extending ConfiguredEndpointDefinition?
Comment by Christopher Zimmermann [ 25/Apr/23 ]

Hi marc.johnen thank you for your detailed input. It's appreciated and we do consider it. 

There are a number of related tickets, but I have created one specifically for the namespace problems of the referenceResolver. 
https://jira.magnolia-cms.com/browse/MGNLREST-682

I also created a wiki page with some ideas - maybe you can have a look and see what you think and possibly add more ideas. Feel free to edit the page. (You too NDQ !)
https://wiki.magnolia-cms.com/display/WIKI/Improve+Reference+Resolving

Generated at Mon Feb 12 06:25:36 CET 2024 using Jira 9.4.2#940002-sha1:46d1a51de284217efdcb32434eab47a99af2938b.