adaptTo() Talk 2019: AEM Vorlagen Editor
Mit der Einführung des Vorlagen-Editors und der Content Richtlinien steht ein leistungsfähiges Werkzeug zur Verfügung. Mit dem Vorlagen-Editor können Vorlagen definiert werden, welche eine Beschreibung, Grundstruktur und anfängliche Inhalte enthalten. Damit kommen jedoch auch Fallstricke, die Projekte in Schwierigkeiten bringen können. Sehen Sie sich kostenlos den Vortrag von Stefan Seifert, pro!vision, auf der adaptTo() 2019 an.
Dieser Vortrag auf der adpatTo() 2019 konzentriert sich auf praktische Erfahrungen mit dem Vorlagen-Editor, z.B.
Kontrolle des Dekorationsauszeichnungs- und Stilsystems
Gute Mischung zwischen statischen und bearbeitbaren Teilen
Vorsichtiges Umgehen mit Verschachtelungsbehältern / Absatzsystemen
Wie man die Vorlagendefinitionen über Stufen und Systeme verteilt
Der Vortrag ist nur in Englisch verfügbar.
Dauer: 30 Minuten
Stefan Seifert, pro!vision
Stefan ist Gründer und CTO der pro!vision GmbH, Berlin. Er arbeitet seit über 15 Jahren als Architekt mit dem Adobe Experience Manager (AEM) und dem zugrunde liegenden Stack. In der Open-Source-Welt ist Stefan Mitglied der Apache Software Foundation, Committer und PMC-Mitglied für Apache Sling, Committer für Apache Felix und Committer und Gründer von wcm.io und seinen Unterprojekten.
adapTo Talk: AEM Template Editor in practice
Moderator: Welcome to second day of adapTo 2019 and today, first talk will be Stefan Seifert from pro!vision with his talk about the Template Editor in practice. Let's welcome Stefan on stage.
Stefan Seifert: Yes. Thank you and have a good morning. I'll skip about me because you already know me from yesterday. So, first, I want to have some quick stats about what you are using. Who of you is using in production editable templates in AEM? Okay. There is perhaps 20, 30 persons I would think. Okay. And, yeah, who still prefers the classic static templates? Okay, probably the same. So, we are perhaps 50/50 here. Okay. And who is using the AEM Responsive Grid together with AEM Layout mode to do your responsive layout? Okay. Perhaps 12 or so. Okay. Okay. Thanks. Yeah, this talk is about the template, editable template and this is not a learning tutorial video. You have this online. You have documentation and so on. It is just some lessons learned from using the Template Editor and practice and some tips or workarounds how to come up with some, yeah, changes you can have with it. Still, short recap what are editable templates. Editable templates replace, in some way, static templates. Of course, you can still use both and AEM static templates are not duplicated. You can even use them probably in the same project having some templates editable, something that is not but the recommendation from Adobe is use only editable templates for new projects. And the difference to static templates is that the editable template is a structure which means, for example, you have multiple columns for different components, they allowed components in the different columns and the policies are stored as configuration and not hard-coded as what is the case with static templates. And this configuration is stored in /conf and not in /apps where the rest of your application code resides.
So, with these new editable templates, there is a new role in your teams. You do not only have a developer who develops application and components and static templates and the page author who enters the content and is just user of your application but you also have a role that is somewhat in between on those two, the template author. He should be a power user at least or perhaps a developer. He has to know your components very well and AEM as well but he works on the author instead and then defines, yeah, the editable template with all its policies and probably the layout as well. And here's an example, a random example how editable template may look like. Here it may look different but you see the three types of possible components you have editable templates. The orange one are components which are defined the editable template but are locked down which means they are visible to the author but they cannot be edited, they cannot be moved, they can be removed. They are just static, fixed parts of the template.
Static parts of the template
For example, yeah, header, navigation and footer component. Then the light blue ones are also locked in the template editor which means these components cannot be moved or removed but they can be edited. For example, this one is an image component where the image can be changed on perhaps caption and so on as well and these two are paragraph systems or layout container components which means the author can put in there any number of components but only of types you allow in the policies which you allowed components settings. And the components that are included here are not many included components but you can add a default set of components and initial content but this is just some, yeah, perhaps example that can be changed or removed by the author after creating the page. And this is a quick recap how the content structure of the editable templates and the related content structure is. This is your content page. One content page, we have of course multiple pages in the site which the author creates. This content page is a reference to the template and if it is an editable template, it is pointing to a template in the conf folder and not in the apps folder as was in static templates before and this points to the editable template configuration in the conf folder and this is usually structured in these three major parts structure. So, it defines again perhaps multiple columns in your template that serves the fixed part of your template probably initial content. It is optional and mappings to policies. So, this folder does not contain the policies itself, it just maps your fixed columns and the structure, your fixed components with defined structure.
Mapping of columns and structure
For example, your two layout containers and perhaps your one in root container and maps them to content policies which contain the, for example, list of allowed components. The benefit of this operation is you have a separate storage of policies. You can reuse these policies. They are named in different templates. And for example, for five templates, you can reuse the policy for the left column, for the teasers and all of these five templates if you want or if you have two different ones. So, this is a shared set of policies and last but not the least, in your content, you have also references to different components. These are the fixed ones which are only contained in the structured template or the ones edited entered by the author and all these are still the classic components you know them for years located in your application folder with html grid sling models and whatever part of the application. So, from the component development view, there is no such a big difference between editable and static templates. The only difference is that probably you have make more use of the design mode in your components because the design mode is defined as dialogue to be used in the policies and no longer the design mode as it was before the design dialogue. Okay. Now, I have collected a list of challenges or problems and solutions or workarounds for those at least.
Challenges and solutions / workarounds
First one, if you do not take care and just start developing your editable template, you may end up in a mess. For example, this is a screenshot of a real-life project I have seen. This is the editable template. It has some hierarchies in it, some nested but it is not really visible here. If you end up where the templates are like these, I think the persons taking up the template author will not be your friend any longer because it is really unmanageable. Have an eye also how you structure your editable template and try to minimize it to those parts that are really required because keep in mind that in the root of our editable templates, there is also a page component which is the same as the static component. I'm just showing it in a short demo. What you can do? Move all parts that are normally static like header and footer and perhaps even navigation if you do not plan to make it changeable from template to template and navigations remain and the footer part. They do not have to include as editable in the component, even not as structure editable because if you include this directly in your page component, then it is not visible, it is not cluttering the edit mode of the editable templates anymore. I'm showing you this soon and you can always mix to any degree static part and editable parts of your template because if you look at editable template, it has a reference to a template type which is basically also an editable template but just a template for the template.
If you are creating a new template, this is copied and you start from it, you can change but this template type reference page component and this page component is technically the same you are used to when you develop static template which means this page component can contain much more than just the entry point to editable templates. I'm showing this in a demo what this means. This is a very simple demo application. It looks the same like the one I showed yesterday but it is implemented even simpler with only some bare bone AEM component and this is an editable template definition. In this case, I have a header which is Start Bootstrap and I have a footer and even navigation. It is supposed to be here because I have no navigation points and all those are included statically and the only things, I have included here in the template itself are image header component and a paragraph system which allows in this case only two components. It is very easy editable template and if I look at the code for this. Let's start with the template definition itself. It starts just homepage template. In the structure, okay, here's a structure component. Just the image component header and the paragraph system but here is also the link to the page component. It is the same as it was usually for static templates and let us have a look at this. It is in the apps folder, so I'm looking here in the apps folder. Global, page and into the html and normally, if you just use editable templates as it is contained in the, for example, product demos by Adobe, we have just this part here. This is just the entry point to tell the editable template container, okay, put your root container editable template here and provide the edit capability but around this container, you can place any markup and include other components as your have done always for static templates. For example, here I have included a bit of rubber markup and from navigation and the footer. So, this is my recommendation.
If you start creating editable template, think about which are parts you never want to have editable and contains in your root component or have multiple page components and then include this editable template root container only at this level where you want to leave the freedom for the template authors to edit the templates. This usually makes the editable template much more editable than putting all components within the grid instead of note. Okay. Second one, policies for nested paragraph systems or layout container. Perhaps I will show you in the page itself. I have one page with a very big paragraph system. Here, this is one big paragraph system going over the whole this and within this paragraph system, I have two big components. One, services component here where I can edit the label and the subheading and another big component, portfolio and those two components, service and portfolio have a nested paragraph system in there. Within those I can edit this one here, service item and service link list components. And even at third level within the service link list component, I can add more items like link items just to add new link. I have a hierarchy of three nested paragraph systems and now I want to control for each of this level which components are allowed to add or not.
Editable template mode
Let's go to the editable template mode. And yes, here this is the main paragraph system. Here, I have allowed service and portfolio, those wrapper components which contain a paragraph system in it as well. For them, it is easy. I just go to the policy editor, it is just inheriting from the layout container and so, as usual, I can just set okay within these services I allowed, service items, service link list but how can I know configure which component are allowed for this service item link list component which contains another nested paragraph system? Here, I have no button to add policy and here neither. This is just not possible to define if I do a double click here which components are allowed and because there is no policy, it allows the component from the parent paragraph system which I do not want because, you know, if nested has the same component, it would be an endless loop, not nice but there is a trick to allow this. If in this outer paragraph system, you would change the policy and allow your subcomponent as well and this type the link list, then I can edit a policy and, for example, only allow service link list item. So, okay.
Next level paragraph system
And now, I'm halfway through because here, only link list items allowed but if I go to the next level paragraph system here, to the outer paragraph system, I can here the service link list as well but this is not what I intended because this should only be allowed within the services component. And here's the ugly trick.
I just go here to the policy editor again and remove the link list again and so, going back to the page, going to the outer part of this, I have only those two and going to my link list component, I have only link list. It is solved but only because the template editor forgot to remove the policy mapping I have. Luckily, I have added here. You do not see the policy any longer but you can edit again and edit it, so, it is really ugly but it works. If this is too ugly for you, you could also use the wcm.io parsys which does not use policies at all but defines a list of allowed components directly in the component, page component with the special mapping but this only works for paragraph system. For other components like image components or whatever component you want to set policies, you have to use this trick. This trick has a limitation. If you have multiple columns, for example, in your template, this limitation you cannot define different policies, for example, left and right column in this paragraph system because you have only inheriting from the root, a hidden root policy but for the most cases, it should be a workaround. That's okay. Next one.
When you want to define which templates are allowed at which position within your site within your content hierarchy, the current recommended solution of Adobe is using this cq:allowedTemplates property within your site. That means in your root site, you set this property and allow, for example, perhaps using all templates of your template set but this can get cumbersome if you have (a) lots of sites because you have to find it for each of the site and if you add a new template and does not match by apps, you have to add it in all sites again and if you want to define more fine-grained rules, it gets difficult. For example, if you have this set up here in this root level, you want to allow template A, B, C in the section, perhaps it is a new section you want to allow only template D, perhaps a news posting template and here you want to only allow templates which have D as parent and so on. This is difficult to define with this property because you have to try at every page level of a different list and so on. It is not really nice. And the tip is really simple. From static template, you know these properties allowedPaths, allowedParents, allowedChildren. They are not supported in the template editor under UI but you can still set them directly in the repository and with this, yeah, with this it is working as expected. Just showing you shortly in the code. Going back in template definition here in the homepage and let's look at the content template here. I've just added here allowedParents, only allowed as a parent as one of our own application templates and allowedPaths anywhere from this path. So, you can use the same whereas you have used the static templates for editable templates as well but you have to add it manually in the repository or in your grid structure. Okay. Next one, semantic naming.
Whenever you create structure components or add policies, they get autogenerated names which is not always the problem but if, for example, the root structure in your template, for example, separating the main column and the teaser column and so on, then the main column is named responsive grid and the teaser column is named responsive grid and any number behind this and if you later have the need to access your content from your code, this is not really nice because then you look for the teasers and responsive grid each in set number and so on. So, my tip is really simple. Create the template using template editor but before you are using it in production, before you are using it to enter content, go to the template definition manually, either in your grid structure or in the repository and just rename the notes to sensible names like content or left column or teaser or whatever, and if you then create the content of the template, it has nice semantic names you are used to when you use static templates. And for policies, the same. This is not so important here because policies are not starting the content, they only start in templates and in the template mappings but again, if you do not need to merge different template definitions, it is easier to have clear names in the policy notes as well and not just autogenerated names. Yeah. Next one, it happens that you want to reuse parts of templates and other templates or have a set-up. Well, the simple sharing of policies is not enough because if you have lots of templates and a complex set of policies. For example, you have allowed ten components in your template and you have specific set of policies for each of these ten components and need these multiple templates, you have an all system templates again and again defines those policies. Of course, you can copy your template and so you do not have to enter it again but then, if you change the policy, you are changing all ten templates.
What is the solution of this if you have really complex template sets?
Well, there is no really a solution out of the box unfortunately. By design, Adobe has decided to not support something like massive laid template or anything like this because it probably would make UI of the template too complicated. Again, if your main concern is with definition of allowed components, you could use, for example, the wcm or paragraph system which defines a list of a lot of components in the application, not in the template definition thus it could make it easier especially if you have small even if it is like a link list component and the link list item. You never want any other component in your link list component. You can define it in your code and you do not have to repeat in policies in all templates again and again. So, these small examples are - and you can mix it. You can use responsive grid for the main paragraph system perhaps if you ought not and use for example, wcm or parsys for the small paragraph systems which have only very limited allowed list of components. Next one. You may get into role conflicts as well as conflicts with people managing your application and content. The chances - okay, you have your template created, a beautiful set of templates and policies.
Normally, the initial version of those templates and policies are created by the developer team because they know their components best and they know what were the requirements and they come up with a good starting set of templates and policies, and also major updates. For example, if there are brand new features, usually the dev team is responsible as well for delivering you a new set of templates for this or updating the templates. So, the major updates are done by this team as well. Then, you have the person taking in this template author was a power user because this was the main goal of Adobe. Giving the power users a tool to edit the templates themselves. So, marketing department to let them quickly react to changes and quickly tend to market without waiting for the development team until the new release is prepared and so on. So, they start also editing those templates, perhaps creating variations of existing templates or doing slight modifications on some policies. Nice. They can do it in a UI. It is one's grasp but it is how it works. It is quite easy to do and quickly done and can be published to the publishing teams but usually, you have not one instance where all people is working with multiple environments. We have, for example, development environment where your dev team is working and the production environment where your power users are working. And usually, the templates and policies versus major updates are deployed in development first, perhaps even more stages this way and so on and then pushed to production environment.
But now, we have a clash because when a new version is shipped, perhaps new major features and type of definitions and the template editors also have done a lot of changes here, yeah, only one of them can win because there is no concept, there is no tool to automatically merge or change comes from two parties editing. Either you overwrite all changes within your deployment from the power users making them even less your friends after you - perhaps it is too complex template definitions or you require to repeat all those devs you have done with the dev team again on the prod environment which is, of course, very error prone, you may forget something. Yeah, and there is no support for easy merging, no easy way back. What is the solution for this? Of course, easiest but quite unsatisfying solution is just tell the power users keep your hands away from the editable templates. We, the development team, are giving you all what you need and deploy application and then all is well as expected but, of course, the problem then is first, you lose this quick time to market features and yeah, why do we have this user interface and so on, we could just stick with static templates.
The only minor solution currently is if you want to allow both. Before you do a new release from your development team with perhaps a major template updates, define some way export back the updated template definitions from the prod system, perhaps quantum package and merge the melody and your git repository and your def stream and then get back to changes from the prod system but it is still acquired unsatisfying solution and it gets even a bit more complex. This is usually a set up you have with the customers. You have the dev environment, you have QA environment, you have perhaps prelive environment and a prod environment, all something prod life but all with some of sample content, some of ruler content and yeah, what are you doing with your template definitions because Adobe says templates are define on prod. Nice but the dev is working on development, the QA is working on QA and the marketing department is working no prelive to test their new content and so on. And what is the true source for your template definition in this scenario? If prod does change, dev does change, something is deployed, you never know which system, which stage has a correct and latest version of template definitions and now consider a support case. Someone is calling you via phone, hey, I'm using this template and it is not working and you say just it works on my machine. You know this from the past. Very ugly.
You just have to make sure you have a true source for your template definitions. The easiest solution again template authors, keep your hands away from the template editor and the dev team is always pushing the newest templates together or again, implement a backchannel. You have to do this manually somehow from the prod system and perhaps allowing small changes in prod system and pulling those changes back in your git repository and deliver them back into your next change but it is a hassle to really make sure no changes are lost and there is also no good solution. I experimented a bit, for example, subfolders. This would be a solution.
For example, having a main template definition folder for your main set of templates and having a subfolder inheriting policies from the folder path and allowing the template on production only, adding new template in subfolder which would not be overwritten but it just does not work although the template is basically based on sling context aware configuration, not everything works because they are doing some shortcuts in the code and not really using configuration as to what intended to and always. And also, the inheriting of policies from Apache configuration folder works some way but needs a strength result. For example, you could reuse a policy from an inherited folder, but once you changed it, it is copied and yeah, strengthening it. The UI just does not support this used case with inheritance of policies. You start back with doing it manually somehow changing porting back the prod changes to a template definitions or just do not allow, just put it only the definitions on prod and doing it only in the dev teams. Yeah, just as here. Deploy as usual the implication and implement a manually backchannel with changes done on the template definition on prod. Yeah, so let's sum up. Template Editor and Policies are very powerful, very useful but in practice, you have to award the pitfalls to not run into situations where you do not lower nor do no longer now the true source or template definitions. Do you have really the same definitions in all stages and so on. So, use deployment strategy with care and keep your template which is really streamlined into the point only the part you want to have editable. Yes. Demo Project also a good conversation but Adobe about the template that it is tough and of course the documentation is also quite good. Do you have questions?
Audience 1: Hi. I have one remark actually. It is about style system use. I think that's one of the most downfalls of the template system that we have because as a developer, you want to add style system rules for classes, et cetera, and that's something you need to deploy from your code and I think that's why you also mention that you need to have some backfall. I don't know how you feel about that.
Stefan Seifert: Can you repeat the first?
Audience 1: So, yeah. I think one of the most - the worst quirks you have right now is the style system.
Stefan Seifert: Yeah.
Audience 1: Because that's actually, that's heavily maintained by your dev team.
Stefan Seifert: Yeah.
Audience 1: And that's something you can't allow power user to do.
Stefan Seifert: Yeah, correct. I think if you really want to allow the marketing team to apply style changes and style system on the fly, you also need to implement a way to, for example, upload additional style snippets or anything and occlude them as well perhaps an asset or so in your application and then your front-end developer could prepare a style snippet addendum for your sister styles, upload it and then these new styles can be edited but again, this is not included as built-in features. You have to do some manual steps to allow this. Yeah.
Audience 2: Hi. Regarding the policy, did you have opportunity to check the performance of the policy? Because when I'm checking for filing the code, I realized that half time of component, wondering if to take the proper policy and I'm wondering if there is some caching that is needed on this level, some custom caching strategy.
Stefan Seifert: It would be interesting to have statistics for this. Of course, if you rely heavily on the spatial caching, it's not that big issue but yes, if you flash that spatial cache often or perhaps even uncached pages for some reason with personalization or so, it may be a problem. So, no, I'm currently not aware of having really a bit caching layers. Perhaps this should be, yeah. I'm not sure if it's the main performance impact is in sling itself, for example, and configuration lookup which is used or in upper layer in AEM itself and depending on this, we can do something in sling to make it a more performant. If it's in the AEM code itself, of course, we should report it back to Adobe teams to see if they can put it.
Audience 3: Good morning. Regarding core components, they heavily rely on editable templates and I assume your core components also rely on that.
Stefan Seifert: Yeah.
Audience 3: So, there is no way to use parsys with image and policies with like set of images. So, it is still the truth and better to use editable templates even like restrict for developers only but editable templates.
Stefan Seifert: Basically, yes. If you look back into talk I have yesterday with wcm.oi handler, if you use the first layer, yes, you are heavily based on policies but if you are using the wcm handler directly using its APIs and reusable fragments and so, you do not have to use policies you do not want to. So, it offers a lot of ways to display images, run a link and so on without having to rely to policy. You could use policy but it is only an option. You can also define the media format and so on and responsive setting, either directing your code or in component properties so you are more flexible with your custom components.
Moderator: Thank you, Stefan.