Expand my Community achievements bar.

SOLVED

Extending Tabs Component and remove the space and place - in place of ID

Avatar

Level 1

I am extending tabs component here is the content XML of core component

 

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:granite="http://www.adobe.com/jcr/granite/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
    jcr:primaryType="nt:unstructured"
    jcr:title="Tabs"
    sling:resourceType="cq/gui/components/authoring/dialog"
    extraClientlibs="[core.wcm.components.commons.editor.dialog.childreneditor.v1,core.wcm.components.tabs.v1.editor]"
    helpPath="https://www.adobe.com/go/aem_cmp_tabs_v1"
    trackingFeature="core-components:tabs:v1">
    <content
        granite:class="cmp-tabs__editor"
        jcr:primaryType="nt:unstructured"
        sling:resourceType="granite/ui/components/coral/foundation/container">
        <items jcr:primaryType="nt:unstructured">
            <tabs
                jcr:primaryType="nt:unstructured"
                sling:resourceType="granite/ui/components/coral/foundation/tabs"
                maximized="{Boolean}true">
                <items jcr:primaryType="nt:unstructured">
                    <containerItems
                        jcr:primaryType="nt:unstructured"
                        jcr:title="Items"
                        sling:resourceType="granite/ui/components/coral/foundation/container"
                        margin="{Boolean}true">
                        <items jcr:primaryType="nt:unstructured">
                            <columns
                                jcr:primaryType="nt:unstructured"
                                sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns"
                                margin="{Boolean}true">
                                <items jcr:primaryType="nt:unstructured">
                                    <column
                                        jcr:primaryType="nt:unstructured"
                                        sling:resourceType="granite/ui/components/coral/foundation/container">
                                        <items jcr:primaryType="nt:unstructured">
                                            <containerItems
                                                jcr:primaryType="nt:unstructured"
                                                sling:resourceType="core/wcm/components/commons/editor/dialog/childreneditor/v1/childreneditor"/>
                                        </items>
                                        <granite:data
                                            jcr:primaryType="nt:unstructured"
                                            max="20"
                                            max-length="38"
                                            min="2"/>
                                    </column>
                                </items>
                            </columns>
                        </items>
                    </containerItems>
                    <details
                        jcr:primaryType="nt:unstructured"
                        jcr:title="Details"
                        sling:resourceType="granite/ui/components/coral/foundation/container"
                        margin="{Boolean}true">
                        <items jcr:primaryType="nt:unstructured">
                            <columns
                                jcr:primaryType="nt:unstructured"
                                sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns"
                                margin="{Boolean}true">
                                <items jcr:primaryType="nt:unstructured">
                                    <column
                                        jcr:primaryType="nt:unstructured"
                                        sling:resourceType="granite/ui/components/coral/foundation/container">
                                        <items jcr:primaryType="nt:unstructured">
                                            <title
                                                jcr:primaryType="nt:unstructured"
                                                sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
                                                fieldDescription="Enter the Container label.75 characters maximum allowed."
                                                fieldLabel="Container label"
                                                maxlength="{Long}75"
                                                name="./title"
                                                required="{Boolean}true"/>
                                            <description
                                                jcr:primaryType="nt:unstructured"
                                                sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
                                                fieldDescription="Enter the Descriptipn"
                                                fieldLabel="Description"
                                                name="./description"/>
                                        </items>
                                    </column>
                                </items>
                            </columns>
                        </items>
                    </details>
                    <properties
                        jcr:primaryType="nt:unstructured"
                        jcr:title="Properties"
                        sling:resourceType="granite/ui/components/coral/foundation/container"
                        maximized="{Boolean}true"/>
                    <accessibility
                        jcr:primaryType="nt:unstructured"
                        jcr:title="Accessibility"
                        sling:resourceType="granite/ui/components/coral/foundation/container"
                        margin="{Boolean}true"/>
                </items>
            </tabs>
        </items>
    </content>
</jcr:root>

and this is the sightly file that is default in  Tabs component

 

<div data-sly-use.tabs="com.adobe.cq.wcm.core.components.models.Tabs"
     data-sly-use.templates="core/wcm/components/commons/v1/templates.html"
     data-panelcontainer="${wcmmode.edit && 'tabs'}"
     id="${tabs.id}"
     class="cmp-tabs"
     data-cmp-is="tabs"
     data-cmp-data-layer="${tabs.data.json}"
     data-placeholder-text="${wcmmode.edit && 'Please drag Tab components here' @ i18n}">
      <div class="tab-header">
        <h2>${properties.title}</h2>
        <sly data-sly-test="${properties.description}">
          <div class="tabs-description">
            <p>${properties.description} </p>
          </div>
        </sly>
      </div>
    <div class="tab-wrapper">
    <ul data-sly-test="${tabs.items && tabs.items.size > 0}"
        data-sly-list.tab="${tabs.items}"
        role="tablist"
        class="cmp-tabs__tablist"
        aria-label="${tabs.accessibilityLabel}"
        aria-multiselectable="false">
        <sly data-sly-test.isActive="${tab.name == tabs.activeItem}"/>
        <li role="tab"
            id="${tab.title}"
            class="cmp-tabs__tab${isActive ? ' cmp-tabs__tab--active' : ''}"
            aria-controls="${tab.id}-tabpanel"
            tabindex="${isActive ? '0' : '-1'}"
            data-cmp-hook-tabs="tab">${tab.title}</li>
    </ul>
    <div data-sly-repeat.item="${tabs.items}"
         data-sly-resource="${item.name @ decorationTagName='div'}"
         id="${item.id}-tabpanel"
         role="tabpanel"
         aria-labelledby="${item.id}-tab"
         tabindex="0"
         class="cmp-tabs__tabpanel${item.name == tabs.activeItem ? ' cmp-tabs__tabpanel--active' : ''}"
         data-cmp-hook-tabs="tabpanel"
         data-cmp-data-layer="${item.data.json}"></div>
    <sly data-sly-resource="${resource.path @ resourceType='wcm/foundation/components/parsys/newpar', appendPath='/*', decorationTagName='div', cssClassName='new section aem-Grid-newComponent'}"
         data-sly-test="${(wcmmode.edit || wcmmode.preview) && tabs.items.size < 1}"></sly>
    </div>
</div>

 

 

My Task is to remove any white space present in id="${tab.title}" and change it to - symbol right now it is printing as %20 

I created a java class that is picking up the title or any other text field  but I want to change the child editor node of XML how can I achieve this.

 

For reference I am attaching Java class

@Model(adaptables = {Resource.class, SlingHttpServletRequest.class},
defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL,
resourceType = "core/wcm/components/tabs/v1/tabs",
adapters = { Tabs.class, ComponentExporter.class })
public class CustomTabsModel implements Tabs, ComponentExporter  {

}

 

Topics

Topics help categorize Community content and increase your ability to discover relevant content.

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

Hi @RohanKa1 ,

Please try to use the annotation  @Self and @Via

Reason for this is that when you inject the Core Component model using @Self annotation, it may not be able to render the implementation of the interface from the Core Component’s model.

So to avoid this you must implement all the methods of the Core Model’s interface individually in your Model. .

 

import com.adobe.cq.export.json.ComponentExporter;
import com.adobe.cq.wcm.core.components.models.Tabs;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.models.annotations.DefaultInjectionStrategy;
import org.apache.sling.models.annotations.Model;

@Model(
    adaptables = {Resource.class, SlingHttpServletRequest.class},
    defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL,
    resourceType = "core/wcm/components/tabs/v1/tabs",
    adapters = {Tabs.class, ComponentExporter.class}
)
public class CustomTabsModel implements Tabs, ComponentExporter {

    @Self @Via(type=ResourceSuperType.class)
    private Tabs tabs;
    
   // Must implement all the method of core component.

    @Override
    public String getId() {
        // Get the original ID from the underlying implementation
        String originalId = tabs.getId();

        // Replace spaces with hyphens
        return originalId.replaceAll("\\s", "-");
    }

}

 

 

 

 

 

Thanks
Tarun

View solution in original post

2 Replies

Avatar

Community Advisor

Hi @RohanKa1 
try this way

 

import com.adobe.cq.export.json.ComponentExporter;
import com.adobe.cq.wcm.core.components.models.Tabs;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.models.annotations.DefaultInjectionStrategy;
import org.apache.sling.models.annotations.Model;

@Model(
    adaptables = {Resource.class, SlingHttpServletRequest.class},
    defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL,
    resourceType = "core/wcm/components/tabs/v1/tabs",
    adapters = {Tabs.class, ComponentExporter.class}
)
public class CustomTabsModel implements Tabs, ComponentExporter {

    // ... other methods and fields

    @Override
    public String getId() {
        // Get the original ID from the underlying implementation
        String originalId = tabs.getId();

        // Replace spaces with hyphens
        return originalId.replaceAll("\\s", "-");
    }

    // ... other methods
}

 

the getId() method is overridden to modify the ID as needed. The tabs field represents the original Tabs implementation that you are extending. Ensure that your class properly implements the Tabs interface by delegating to the underlying tabs object for other methods. Make sure to replace "core/wcm/components/tabs/v1/tabs" with the correct resource type for your extended Tabs component.

 



Avatar

Correct answer by
Community Advisor

Hi @RohanKa1 ,

Please try to use the annotation  @Self and @Via

Reason for this is that when you inject the Core Component model using @Self annotation, it may not be able to render the implementation of the interface from the Core Component’s model.

So to avoid this you must implement all the methods of the Core Model’s interface individually in your Model. .

 

import com.adobe.cq.export.json.ComponentExporter;
import com.adobe.cq.wcm.core.components.models.Tabs;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.models.annotations.DefaultInjectionStrategy;
import org.apache.sling.models.annotations.Model;

@Model(
    adaptables = {Resource.class, SlingHttpServletRequest.class},
    defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL,
    resourceType = "core/wcm/components/tabs/v1/tabs",
    adapters = {Tabs.class, ComponentExporter.class}
)
public class CustomTabsModel implements Tabs, ComponentExporter {

    @Self @Via(type=ResourceSuperType.class)
    private Tabs tabs;
    
   // Must implement all the method of core component.

    @Override
    public String getId() {
        // Get the original ID from the underlying implementation
        String originalId = tabs.getId();

        // Replace spaces with hyphens
        return originalId.replaceAll("\\s", "-");
    }

}

 

 

 

 

 

Thanks
Tarun