The content element above is showing a teaser. The resource type of the teaser component is
composum/pages/components/element/teaserThe base implementation shipped as part of the Composum Pages Components is located in the /libs resource resolver root. The component declaration here
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:cpp="http://sling.composum.com/pages/1.0"
        xmlns:jcr="http://www.jcp.org/jcr/1.0"
        xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
        xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
        jcr:primaryType="cpp:Component"
        sling:resourceSuperType="composum/pages/components/element"
        jcr:description="a teaser to guide to another page"
        jcr:title="Teaser"
        category="[Teaser,General,Blueprint]">
    <jcr:content
            jcr:primaryType="nt:unstructured">
        <properties
                jcr:primaryType="nt:unstructured">
            <variation
                    jcr:primaryType="nt:unstructured"/>
            <title
                    jcr:primaryType="nt:unstructured"
                    i18n="{Boolean}true"
                    text="plain"/>
            <subtitle
                    jcr:primaryType="nt:unstructured"
                    i18n="{Boolean}true"
                    text="plain"/>
            <text
                    jcr:primaryType="nt:unstructured"
                    i18n="{Boolean}true"
                    required="{Boolean}true"
                    text="rich"/>
            <link
                    jcr:primaryType="nt:unstructured"/>
            <linkTitle
                    jcr:primaryType="nt:unstructured"
                    i18n="{Boolean}true"
                    text="plain"/>
            <linkTarget
                    jcr:primaryType="nt:unstructured"/>
            <icon
                    jcr:primaryType="nt:unstructured"/>
        </properties>
        <elements
                jcr:primaryType="nt:unstructured">
            <image
                    jcr:primaryType="nt:unstructured"
                    type="composum/pages/components/element/image"/>
            <video
                    jcr:primaryType="nt:unstructured"
                    type="composum/pages/components/element/video"/>
            <links
                    jcr:primaryType="nt:unstructured"
                    type="composum/pages/components/element/link/set"/>
        </elements>
    </jcr:content>
</jcr:root>defines a placable component (cpp:Component primary type). Such a Sling component is registered by the Pages Component Manager automatically and offered in the various component type selector widgets for insertion into a container of a content page.
Teaser Scripting
<%@page session="false" pageEncoding="UTF-8" %>
<%@taglib prefix="cpp" uri="http://sling.composum.com/cppl/1.0" %>
<cpp:defineObjects/>
<cpp:model var="teaser" type="com.composum.pages.components.model.teaser.Teaser">
    <cpp:include test="${teaser.valid}" replaceSelectors="${teaser.variation}"/>
</cpp:model>This looks very simple because the main template is delegation the rendering to the teasers variation declared by a property of the teaser. This property 'defined' in the teasers edit dialog.
Edit Dialog
<%@page session="false" pageEncoding="utf-8" %>
<%@taglib prefix="cpp" uri="http://sling.composum.com/cppl/1.0" %>
<cpp:defineFrameObjects/>
<cpp:editDialog title="@{dialog.selector=='create'?'Create a Teaser':'Edit Teaser'}">
    <cpp:editDialogTab tabId="teaser" label="Properties">
        <div class="row">
            <div class="col col-xs-8">
                <cpp:widget label="Teaser Title" property="title" type="textfield" i18n="true"/>
            </div>
            <div class="col col-xs-4">
                <cpp:widget label="Variation" property="variation" type="select" hint="render type"
                            options="default,bgimage,bgvideo,symbol" default="default"/>
            </div>
        </div>
        <cpp:widget label="Subtitle" property="subtitle" type="textfield" i18n="true"/>
        <cpp:widget label="Text" property="text" type="richtext" i18n="true" required="true"
                    height="120px"/>
        <cpp:include resourceType="composum/pages/components/element/link" subtype="edit/dialog"
                     replaceSelectors="embedded"/>
    </cpp:editDialogTab>
    <cpp:editDialogTab tabId="image" label="Image">
        <cpp:include path="image" resourceType="composum/pages/components/element/image" subtype="edit/dialog"
                     replaceSelectors="embedded"/>
    </cpp:editDialogTab>
    <cpp:editDialogTab tabId="video" label="Video">
        <cpp:include path="video" resourceType="composum/pages/components/element/video" subtype="edit/dialog"
                     replaceSelectors="embedded"/>
    </cpp:editDialogTab>
    <cpp:editDialogTab tabId="icon" label="Icon">
        <div class="row">
            <div class="col col-xs-7">
                <cpp:widget type="static"
                            value="Alternative to a teaser image or video a symbol can be used. The chosen symbol is not used if an image or video is referenced."/>
            </div>
            <div class="col col-xs-5">
                <cpp:widget label="Symbol" property="icon" type="iconcombobox"
                            hint="<a href='https://fontawesome.com/v4.7.0/icons/' target='_blank'>'FontAwesome'</a> icon key"
                            options="at,asterisk,bookmark-o:bookmark,check,exclamation,eye,info-circle:info,lightbulb-o:lightbulb,question-circle-o:qestion,search,warning,wrench"
                            typeahead="/bin/cpm/core/system.typeahead.json/libs/fonts/awesome/4.7.0/font-awesome-keys.txt"/>
            </div>
        </div>
    </cpp:editDialogTab>
</cpp:editDialog>The Model Class
/* 
 * copyright (c) 2015ff IST GmbH Dresden, Germany - https://www.ist-software.com 
 * 
 * This software may be modified and distributed under the terms of the MIT license. 
 */ 
package com.composum.pages.components.model.teaser; 
 
import com.composum.pages.components.model.ImageRelatedElement; 
import org.apache.commons.lang3.StringUtils; 
import org.apache.sling.api.resource.Resource; 
 
import static com.composum.pages.components.model.text.Text.PROP_TEXT; 
 
public class Teaser extends ImageRelatedElement { 
 
    public static final String PROP_VARIATION = "variation"; 
    public static final String DEFAULT_VARIATION = "default"; 
 
    public static final String PROP_LINK = "link"; 
    public static final String PROP_LINK_TITLE = "linkTitle"; 
 
    public static final String PROP_SUBTITLE = "subtitle"; 
 
    public static final String NODE_IMAGE = "image"; 
    public static final String PROP_IMAGE_REF = NODE_IMAGE + "/imageRef"; 
 
    public static final String NODE_VIDEO = "video"; 
    public static final String PROP_VIDEO_REF = NODE_VIDEO + "/videoRef"; 
 
    public static final String PROP_ICON = "icon"; 
 
    public static final String NODE_LINKS = "links"; 
    public static final String SELECTOR_LINK_SET = NODE_LINKS; 
 
    public static final String SELECTOR_TEXTBLOCK = "textblock"; 
    public static final String SELECTOR_PLACEHOLDER = "placeholder"; 
 
    private transient String variation; 
 
    private transient String subtitle; 
    private transient String text; 
 
    private transient String icon; 
 
    public String getVariation() { 
        if (variation == null) { 
            variation = getProperty(PROP_VARIATION, DEFAULT_VARIATION); 
            if (isHasLinkSet()) { 
                variation += "-" + SELECTOR_LINK_SET; 
            } 
        } 
        return variation; 
    } 
 
    public String getShape() { 
        return isUseVideo() ? "video" : isUseImage() ? "image" : isUseIcon() ? "symbol" : "text"; 
    } 
 
    public boolean isNoAsset() { 
        return !isUseVideo() && !isUseImage(); 
    } 
 
    public boolean isUseVideo() { 
        return StringUtils.isNotBlank(getProperty(PROP_VIDEO_REF, "")); 
    } 
 
    public boolean isUseImage() { 
        return !isUseVideo() && StringUtils.isNotBlank(getProperty(PROP_IMAGE_REF, "")); 
    } 
 
    public boolean isUseIcon() { 
        return !isUseImage() && StringUtils.isNotBlank(getIcon()); 
    } 
 
    public boolean isHasIcon() { 
        return StringUtils.isNotBlank(getIcon()); 
    } 
 
    public String getIcon() { 
        if (icon == null) { 
            icon = getProperty(PROP_ICON, ""); 
        } 
        return icon; 
    } 
 
    public String getSubtitle() { 
        if (subtitle == null) { 
            subtitle = getProperty(PROP_SUBTITLE, ""); 
        } 
        return subtitle; 
    } 
 
    public String getText() { 
        if (text == null) { 
            text = getProperty(PROP_TEXT, ""); 
        } 
        return text; 
    } 
 
    public boolean isTextValid() { 
        return StringUtils.isNotBlank(getTitle()) 
                || StringUtils.isNotBlank(getSubtitle()) 
                || StringUtils.isNotBlank(getText()); 
    } 
 
    public boolean isHasLinkSet() { 
        Resource links = getResource().getChild(NODE_LINKS); 
        return links != null && links.hasChildren(); 
    } 
 
    public String getTextSelector() { 
        return isTextValid() ? SELECTOR_TEXTBLOCK : SELECTOR_PLACEHOLDER; 
    } 
}This looks very simple because the main template is delegation the rendering to the teasers variation declared by a property of the teaser. This property 'defined' in the teasers edit dialog.
the default teaser variation
<%@page session="false" pageEncoding="UTF-8" %>
<%@taglib prefix="cpn" uri="http://sling.composum.com/cpnl/1.0" %>
<%@taglib prefix="cpp" uri="http://sling.composum.com/cppl/1.0" %>
<cpp:defineObjects/>
<cpp:element var="teaser" type="com.composum.pages.components.model.teaser.Teaser"
             cssAdd="@{teaserCSS}_variation_default @{teaserCSS}_@{teaser.shape}">
    <cpn:link test="${teaser.hasLink}" body="true" class="${teaserCSS}_link"
              href="${teaser.linkUrl}" target="${teaser.linkTarget}" title="${teaser.linkTitle}">
        <cpn:div test="${teaser.useImage||teaser.useVideo||teaser.authorMode}" class="${teaserCSS}_asset">
            <cpn:div test="${teaser.useImage||teaser.authorMode}" class="${teaserCSS}_image">
                <cpp:include path="image" resourceType="composum/pages/components/element/image"/>
            </cpn:div>
            <cpn:div test="${teaser.useVideo||teaser.authorMode}" class="${teaserCSS}_video">
                <cpp:include path="video" resourceType="composum/pages/components/element/video"/>
            </cpn:div>
        </cpn:div>
        <cpn:div test="${teaser.useIcon}" class="${teaserCSS}_icon"><i
                class="fa fa-${teaser.icon}"></i></cpn:div>
        <div class="${teaserCSS}_content">
            <cpp:include replaceSelectors="${teaser.textSelector}"/>
            <cpp:include path="links" resourceType="composum/pages/components/element/link/set"/>
        </div>
    </cpn:link>
</cpp:element>the other teaser variations
'bgimage' teaser
<%@page session="false" pageEncoding="UTF-8" %>
<%@taglib prefix="cpn" uri="http://sling.composum.com/cpnl/1.0" %>
<%@taglib prefix="cpp" uri="http://sling.composum.com/cppl/1.0" %>
<cpp:defineObjects/>
<cpp:element var="teaser" type="com.composum.pages.components.model.teaser.Teaser"
             cssAdd="@{teaserCSS}_variation_bg-image"
             style="background-image:url(@{teaser.imageUrl})">
    <cpp:dropZone property="image/imageRef" filter="asset:image">
        <cpn:link test="${teaser.hasLink}" body="true" class="${teaserCSS}_link"
                  href="${teaser.linkUrl}" target="${teaser.linkTarget}" title="${teaser.linkTitle}">
            <cpn:div test="${teaser.hasIcon}" class="${teaserCSS}_icon"><i
                    class="fa fa-${teaser.icon}"></i></cpn:div>
            <div class="${teaserCSS}_content">
                <cpp:include replaceSelectors="${teaser.textSelector}"/>
            </div>
        </cpn:link>
    </cpp:dropZone>
</cpp:element>'bgvideo' teaser
<%@page session="false" pageEncoding="UTF-8" %>
<%@taglib prefix="cpn" uri="http://sling.composum.com/cpnl/1.0" %>
<%@taglib prefix="cpp" uri="http://sling.composum.com/cppl/1.0" %>
<cpp:defineObjects/>
<cpp:element var="teaser" type="com.composum.pages.components.model.teaser.Teaser"
             cssAdd="@{teaserCSS}_variation_bg-video">
    <cpp:include path="video" resourceType="composum/pages/components/element/video/background" mode="none"/>
</cpp:element>