It seems to be quite basic problem, but I still cannot find a nice solution.
I made a component that uses a dialog property.
How could I avoid setting this property for every single page if this component is used also in template?
What I already have tried:
I set name attribute in dialog.xml to absolute path - Component stops working as standalone (dropped into parsys).
Move it to design_dialog.xml - First of all it's conceptually content, so I do not like such move, and again it doeas not make much sense for standalone versions.
Change resource path to absolute, while including in template:
<cq:include path="/content/site/somepage" resourceType="/apps/portal/components/myComponent" />
For the first look it was almost it. Instances included via parsys has it's own path, and Content for template is fetched from single resource... But where to store it, to make template code independent from pages tree structure?
Is there any other nice way to do so? or at least way to improve 3.?
To the original poster, the functionality you are looking for is now supported by Shared Component Properties in ACS AEM Commons (http://adobe-consulting-services.github.io/acs-aem-commons/features/shared-component-properties.html)
Compared to your suggested solutions:
No need for absolute property path required for SCP
Agreed these are "content" properties, so they should be stored as "content" instead of "design". SCP stores these values under the homepage node of a site, making them as genuine of content as any other piece of content.
Agreed that it is bad to have a template hard-coded to a content path of a single site, especially since this makes a multi-site implementation impossible without creating a bunch of templates. SCP does not have this problem, because each site has its own homepage under which the properties are stored.
If I understand correctly, you have a component which may work in two modes:
it may be included statically in the main page renderer via <cq:include>
it may be also dropped into some parsys.
In the first mode component should have some common configuration for all pages and in the second mode it should be configured separately per-instance. The problem is how to create such common configuration.
I think your 3rd solution is perfectly fine assuming that the component configuration is shared by all sites in your CQ instance. At some point it may be too strong assumption, eg. you may have a 3 language branches under /content/site-en, /content/site-fr and /content/site-de and you'd like to make a separate configuration for each branch.
I'd suggest following improvement to the 3rd solution: you may create the shared component under some relative path which will be the same for all pages, like /content/.../configuration/shared-component (where ... may be site1, site2 or site3). Then take first two parts of the current page path, add the /configuration/shared-component suffix and use <cq:include> to include path created in such way.
You may also take a different approach and create a common configuration page referenced by all statically included components. These components may try to find their configuration automatically (via the relative path as above) or they may have a single pathfield that references configuration page.
If you don't like these options (as they assume some site structure or they need some minimal configuration for each component), consider using HierarchyNodeInheritanceValueMap. It allows you to get property from the current resource and if there is no such property, it'll look into the same resource on ancestor pages. Using this you could configure your component just once, in the site root page and inherit configuration across the whole site.
Related
I have a test web page that contains one component, a carousel.
That component was copied from /libs/foundation/components/carousel and what i have modified from the copied component was the property:
sling:resourceSuperType from foundation/components/list to foundation/components/carousel.
My next step was to remove a property from the touch dialog (the property Controls Style).
My problem is that in my web page i keep seeing this property even when it was deleted.
Is this because the resourceSuperType is foundation/components/carousel and because this component stills have the property i'm seeing in the dialog?
This behavior was not like this in AEM 5.
My intention was to copy the component, keep the inheritance (resourceSuperType) and modify the copied component.
What i'm doing wrong?
EDIT: Making some tests i figure out that in AEM 6.0 if i delete a property of the carousel (my copied carousel), the property doesn't appear. BUT in AEM 6.1 the property appears. Where can i found this change between the two versions? or is something else?
When creating an overlay, you're going to find all properties from the original component even if they don't exist in the overlay.
You'll have to explicitly remove the property by adding the sling:hideProperties property of type String[] to your overlay. This will allow you to hide the values otherwise inherited from the node from /libs that you're trying to overlay.
I think you'll find the descriptions of various use cases for the sling:hideProperties property in the documentation quite useful.
As part of of it's resource resolution process, the Sling Resource Resolver has search paths that it looks in to locate a resource.
The two most common search paths are /apps and /libs. With the /apps path taking precedence. The most common usage of this in sling:resourceType where the value is defined as the path below one of these search paths. In your case having a sling:resourceType of foundation/components/carousel would originally return the OOTB components under /libs and when you copied it to the /apps directory it would return the component you put under /apps.
This concept of replacing the existing component with your own component is called an overlay another method is called extending an component where you define a sling:resourceSuperType which, if a resource is not found in the existing path, will pass the request to the superType to see if the resource can be found there.
Before 6.0 this concept of overlay applied only to resource. Which is a node that contains properties (simplistically speaking.) And in most common usage you have to reflect the majority of the component into the new search path to get what you are trying to do.
Starting in 6.0 there was a new concept of a merged resource. That would combine the values of a resource located in multiple search paths. This allowed you to modify or alter the functionality of a component without replicating everything else. You could just change a property at a particular level.
None of this happens automatically. To get this functionality the component needs to be aware of the ResourceMergerApi and use that API when attempting to resolve resources for it to use.
That's why the documentation mentions granite. Granite refers to the new components being written by Adobe that uses the TouchUI and is aware of this new API. With each new release more and more older components are being replaced by the new TouchUI based ones that supports resource merging. Including the carousel.
I'm new to CQ5 and working on a project that deals with refactoring code that uses design dialogs.
Currently, I have a property declared as part of design dialog of my component. It creates a folder in /etc/designs/ for each template my component is used on. Is there a way we can make sure that those property values are stored at one particular configuration in /etc/design(as opposed to multiple)? I need to make sure only one set of configurations is used for all pages that use my component.
Thanks in advance!
Pallavi
The designs are linked to the template and not the whole site.
Hence whenever you configure the component in design mode, the values are stored within the corresponding template under the jcr:content of the configured design page or under /etc/designs/default/jcr:content in case no design is configured.
As far as I know, there is no way to tell AEM to store all the design configurations under one single path, unless you are using absolute paths in your dialog / page configurations.
If you are using multiple templates in your site, there must be one master template (which render global components eg. header/logo/navigation & footer), and all other templates should extend master template to get these global components and change pagelayout for content section.
Saying so, if templates are structured & inherited properly, you should be able to set design dialog property on home page (created using master template) and all internal pages will be able to access those design property OOB. Though child pages (created using other template) can override those design property (if needed for that template) to break inheritance.
I have a requirement where I have 2 clientlibs having different CSS files for my website. The business author should be capable of switching the website look and feel by just changing the path of the design under page properties. While I am able to achieve that requirement by changing the clientlib categories name referred in my JSP of base template of my site, can the same thing be achieved by the business author without actually performing a code level change? Basically, he should be able to select the design path present under the page properties section, and selecting a different design should change the look and feel of the website. Please let me know how this can be achieved.
Note: I have placed my clientlibs under /etc/design/proj-name/ path
The foundation page component is designed to include css link in the head if a file called static.css is present under the design. It's done through the design object.
If you have different css in the static.css file under different designs then the look and feel will change with the design. However you will be stuck with one file and cannot leverage the utility of client libs.
This adobe doc suggest's doing something like this for css and related images
<%= currentDesign.getPath() + "/static/img/icon.gif %>
Data from design dialogs is stored under the design , swapping designs to change look and feel will cause data inconsistencies too.
Why not add a selection widget to the page and use it's value to selectively include different client lib categories instead of relying on the design.
I would like to implement an extensible templating mechanism in AEM, so as to permit component users to control markup for individual projects (designs) without modifying the components' pre-defined JSPs.
I have extended the <cq:include> tag to permit this, by passing a template name, which is then retrieved from the current design, falling back to the default markup when an override does not exist in the design:
<ct:template name="listNav/prev" />
This should load the jsp script from [1], unless the location does not exist, defaulting to [2]:
/etc/designs/projectName/component_templates/listNav/prev.jsp
/etc/designs/component_templates/listNav/prev.jsp
When using the extended tag, I'm receiving the exception (yes, the file exists):
Caused by: org.apache.sling.api.SlingException: javax.servlet.ServletException: javax.servlet.jsp.JspException: Could not find script /etc/designs/component_templates/listNav/prev.jsp
This all works when the component_templates is under /apps. Is there any way to make this work? Is there a better approach? I'd prefer to keep the component_templates with the designs, if possible.
I don't think it is a good idea to put application script to etc. They should be under /apps.
But I think it could work, if you add /etc path to the "Resource Search Path" of this service:
system/console/configMgr/org.apache.sling.jcr.resource.internal.JcrResourceResolverFactoryImpl
you can choose between different "designs" within the advanced page properties tab! afaik you should use this mechanism to declare different designts i.e. stylesheets etc. to your pages and of cause you don't need to modify anything at the jsp's to switch between different styles if implemented properly.
Have a look at this:
Adobe AEM Designs
I'm getting into Google Web Toolkit, and am a little confused about the Entry Points in GWT. Google's docs say:
If you have multiple EntryPoints (the interface that defines onModuleLoad()) within a module, they will all be called in sequence as soon as that module (and the outer document) is ready.
If you are loading multiple GWT modules within the same page, each module's EntryPoint will be called as soon as both that module and the outer document is ready. Two modules' EntryPoints are not guaranteed to fire at the same time, or in the same order in which their selection scripts were specified in the host page.
So does each page in your website need an Entry Point defined for it?
Do you only really NEED an entry point when you have javascript generated based on your Java classes?
Are you able to combine multiple auto-generated-js definitions into a single *.gwt.xml file?
EDIT: Link to quoted source: http://code.google.com/webtoolkit/doc/1.6/DevGuideOrganizingProjects.html
Thanks!
The most straightforward way to make a GWT app is to have a single page for the entire application, and a single top-level module (defined in a .gwt.xml file). Each module has a single EntryPoint class. Then all of your different "pages" are sub-sections of the same page, ideally using GWT's history mechanism to keep track of state changes that in a non-AJAX web app would be new pages. So if you set things up this way you'll need one EntryPoint for your whole app.
The bit of the docs that you quoted (link?) discuss what I think is an advanced use case, where you've got more than one module that you're loading on a single page.
there is one options, U can create maven project with sub projects, means U can create multi entrypoint,
each entry point have own html. See more details