HomeCode Reference › Sling Model snippets

Sling Model snippets

Purpose: Model skeletons for the recurring shapes: component model, child resources, delegation, exporter.

Who this page is for

AudienceWhy it matters to you
Backend engineersDaily

Standard component model (request-adapted)

@Model(adaptables = SlingHttpServletRequest.class,
       adapters = PlanCardModel.class,
       resourceType = "phi-academy/components/plancard",
       defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class PlanCardModel {

    @ValueMapValue private String title;
    @ValueMapValue @Default(values = "") private String subtitle;
    @ValueMapValue @Default(doubleValues = 0) private double monthlyPremium;
    @ChildResource private List<BenefitItem> benefits;
    @ScriptVariable private Page currentPage;
    @OSGiService private PremiumFormatter formatter;

    private String formattedPremium;

    @PostConstruct void init() {
        formattedPremium = formatter != null ? formatter.format(monthlyPremium) : "";
        if (benefits == null) benefits = Collections.emptyList();
    }

    public String getTitle() { return title; }
    public String getFormattedPremium() { return formattedPremium; }
    public List<BenefitItem> getBenefits() { return benefits; }
    public long getCoveredCount() {
        return benefits.stream().filter(BenefitItem::isCovered).count();
    }
}

Child item model (multifield rows)

@Model(adaptables = Resource.class,
       defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class BenefitItem {
    @ValueMapValue @Default(values = "") private String label;
    @ValueMapValue @Default(booleanValues = false) private boolean covered;
    public String getLabel() { return label; }
    public boolean isCovered() { return covered; }
}

JSON exporter variant

@Model(adaptables = SlingHttpServletRequest.class,
       adapters = { PlanCardModel.class, ComponentExporter.class },
       resourceType = "phi-academy/components/plancard",
       defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
@Exporter(name = ExporterConstants.SLING_MODEL_EXPORTER_NAME,
          extensions = ExporterConstants.SLING_MODEL_EXTENSION)
public class PlanCardModel implements ComponentExporter {
    // fields as above …
    @Override public String getExportedType() { return "phi-academy/components/plancard"; }
    @JsonIgnore public Page getCurrentPage() { return currentPage; }  // keep internals out
}

Core Component delegation

@Model(adaptables = SlingHttpServletRequest.class, adapters = Title.class,
       resourceType = "phi-academy/components/title",
       defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class PhiTitle implements Title {
    @Self @Via(type = ResourceSuperType.class) private Title delegate;
    @Override public String getText() { return delegate == null ? null : delegate.getText().toUpperCase(); }
    @Override public String getType() { return delegate == null ? null : delegate.getType(); }
}

Quick navigation