#circuit14 #componentplugin #hashtag
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
	xmlns:cq="http://www.day.com/jcr/cq/1.0"
	xmlns:jcr="http://www.jcp.org/jcr/1.0"
	cq:isContainer="{Boolean}false"
	jcr:primaryType="cq:Component"
	jcr:title="Title"
	componentGroup="Client"/>
						
					<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" jcr:primaryType="cq:Dialog" title="Title" xtype="dialog"> <items jcr:primaryType="cq:TabPanel"> <items jcr:primaryType="cq:WidgetCollection"> <tab1 jcr:primaryType="cq:Widget" title="Title" xtype="panel"> <items jcr:primaryType="cq:WidgetCollection"> <linkText jcr:primaryType="cq:Widget" fieldLabel="Title" fieldDescription="Title for this component" name="./title" xtype="textfield" /> </items> </tab1> </items> </items> </jcr:root>
<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" cq:actions="[text:Title ,-,EDITDELETE,-]" cq:layout="editbar" cq:dialogMode="floating" jcr:primaryType="cq:EditConfig"/> </jcr:root>
public class Title {
	private final String title;
	
	public Title(SlingHttpServletRequest request) {
		ValueMap properties = request.getResource().adaptTo(ValueMap.class);
		this.title = properties.get("title", "DEFAULT TITLE");
	}
	public String getTitle() {
		return title;
	}
}
						
	          		<%@include file="/libs/foundation/global.jsp"%>
<%@ page import="com.client.components.content.title.Title" %>
<c:set var="title" value="<%=new Title(slingRequest) %>"/>
${title.title}
						
	          		The CQ Component Plugin is a Maven/Gradle plugin that uses annotations inside of the backing beans for components to create the required XML files for a component.
<plugin>
    <groupId>com.citytechinc.cq.cq-component-plugin</groupId>
    <artifactId>cq-component-maven-plugin</artifactId>
    <version>2.6.0</version>
    <executions>
        <execution>
            <goals>
                <goal>component</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <componentPathBase>jcr_root/apps/client/components</componentPathBase>
        <defaultComponentGroup>Client Group</defaultComponentGroup>
    </configuration>
</plugin>
						
				buildscript {
    repositories {
       mavenLocal()
       mavenCentral()
    }
    dependencies {
		classpath group: 'com.citytechinc.cq.cq-component-plugin', 
			name: 'cq-component-maven-plugin', version: '2.6.0'
    }
}
						
						componentPlugin {
    componentPathBase = "jcr_root/apps/project/components"
    defaultComponentGroup="Client Group"
}
						
						install.dependsOn generateComponents
@Component(value = "Title")
public class Title {
	@DialogField(fieldLabel = "Title", fieldDescription = "Our title")
	private final String title;
	public Title(SlingHttpServletRequest request) {
		ValueMap properties = request.getResource().adaptTo(ValueMap.class);
		this.title = properties.get("title", "DEFAULT TITLE");
	}
	public String getTitle() {
		return title;
	}
}
					
				@Component(value = "Title")
public class Title {
	@DialogField(fieldLabel = "Title", fieldDescription = "Our title")
	private final String title;
	public Title(SlingHttpServletRequest request) {
		ValueMap properties = request.getResource().adaptTo(ValueMap.class);
		this.title = properties.get("title", "DEFAULT TITLE");
	}
	public String getTitle() {
		return title;
	}
}
					
				@Component(value = "Title")
public class Title {
	@DialogField(fieldLabel = "Title", fieldDescription = "Our title")
	private final String title;
	public Title(SlingHttpServletRequest request) {
		ValueMap properties = request.getResource().adaptTo(ValueMap.class);
		this.title = properties.get("title", "DEFAULT TITLE");
	}
	public String getTitle() {
		return title;
	}
}
					
				@Component(value = "Title")
public class Title {
	private final ValueMap properties;
	public Title(SlingHttpServletRequest request) {
		properties = request.getResource().adaptTo(ValueMap.class);
	}
	@DialogField(fieldLabel = "Title", fieldDescription = "Our title")
	public String getTitle() {
		return properties.get("title", "DEFAULT TITLE");;
	}
}
					
				@Component(value = "Mixed Tabs", tabs = { @Tab(title = "First tab"),
	@Tab(path = "/libs/foundation/components/page/tab_basic.infinity.json"), 
	@Tab(title = "Last tab") })
public class MixedTabs {
	@DialogField(fieldLabel = "Title", fieldDescription = "Our title", tab = 1)
	@MultiField
	private String title;
	@DialogField(fieldLabel = "Image", tab = 3)
	@Html5SmartImage(disableZoom = true, name = "image", allowCrop=true, 
		allowUpload = false, tab = false, height = 150)
	private String image;
}	
					
				@Component(value = "Title")
public class Title {
	@DialogField(fieldLabel = "Title", fieldDescription = "Our title", ranking = 1)
	private final String title;
	public Title(SlingHttpServletRequest request) {
		ValueMap properties = request.getResource().adaptTo(ValueMap.class);
		this.title = properties.get("title", "DEFAULT TITLE");
	}
	public String getTitle() {
		return title;
	}
}
						
					@Component("Title With Link")
public class TitleWithLink extends Title {
	@DialogField(fieldLabel = "Link", fieldDescription = "Our link", ranking = 2)
	@PathField
	private final String link;
	public TitleWithLink(SlingHttpServletRequest request) {
		super(request);
		ValueMap properties = request.getResource().adaptTo(ValueMap.class);
		this.link = properties.get("link", String.class);
	}
	public String getLink() {
		return link;
	}
}
					
				Using objects provides the ability to use dialog elements and authoring experiences across multiple dialogs with no additional effort
public class Link {
	@DialogField(fieldLabel = "Link Path")
	@PathField
	private String linkPath;
	@DialogField(fieldLabel = "Link Text")
	private String linkText;
	public String getLinkPath() {
		return linkPath;
	}
	public void setLinkPath(String linkPath) {
		this.linkPath = linkPath;
	}
	public String getLinkText() {
		return linkText;
	}
	public void setLinkText(String linkText) {
		this.linkText = linkText;
	}
}
				
			@Component(value = "Single Link")
public class SingleLink {
	@DialogField(fieldLabel = "Title")
	private final String title;
	@DialogField
	@DialogFieldSet
	private final Link link;
	public SingleLink(SlingHttpServletRequest request) {
		ValueMap properties = request.getResource().adaptTo(ValueMap.class);
		title = properties.get("title", "DEFAULT TITLE");
		String path = properties.get("linkPath", "/content/defualtpath");
		String linkText = properties.get("linkText", "DEFAULT LINK TITLE");
		link = new Link();
		link.setLinkPath(path);
		link.setLinkText(linkText);
	}
	public String getTitle() {
		return title;
	}
	public Link getLink() {
		return link;
	}
}
					
				@Component(value = "Three Links")
public class ThreeLinks {
	@DialogField(fieldLabel = "Title")
	private final String title;
	@DialogField(fieldLabel = "Link 1")
	@DialogFieldSet(namePrefix = "link1/")
	private final Link link1;
	@DialogField(fieldLabel = "Link 2")
	@DialogFieldSet(namePrefix = "link2/")
	private final Link link2;
	@DialogField(fieldLabel = "Link 3")
	@DialogFieldSet(namePrefix = "link3/")
	private final Link link3;
	public ThreeLinks(SlingHttpServletRequest request) {
		ValueMap properties = request.getResource().adaptTo(ValueMap.class);
		title = properties.get("title", "DEFAULT TITLE");
		link1 = new Link();
		link1.setLinkPath(properties.get("link1/linkPath", "/content/defualtpath"));
		link1.setLinkText(properties.get("link1/linkText", "DEFAULT LINK TITLE"));
		//More Logic
	}
}	
					
				@Component(value = "Multi Links")
public class MultiLinks {
	@DialogField(fieldLabel = "Title")
	private final String title;
	@DialogField
	@DialogFieldSet
	@MultiCompositeField
	private final List links;
	public MultiLinks(SlingHttpServletRequest request) {
		ValueMap properties = request.getResource().adaptTo(ValueMap.class);
		title = properties.get("title", "DEFAULT TITLE");
		links = new ArrayList();
		Iterable resources = request.getResource().getChild("links").getChildren();
		for (Resource r : resources) {
			ValueMap linkProps = r.adaptTo(ValueMap.class);
			String path = linkProps.get("linkPath", "/content/defualtpath");
			String linkText = linkProps.get("linkText", "DEFAULT LINK TITLE");
			Link link = new Link();
			link.setLinkPath(path);
			link.setLinkText(linkText);
			links.add(link);
		}
	}
	public String getTitle() {
		return title;
	}
	public List getLinks() {
		return links;
	}
}	
					
				@Retention(RetentionPolicy.CLASS)
@Target({ ElementType.METHOD, ElementType.FIELD })
public @interface MultiCompositeField {
	boolean matchBaseName() default false;
	String prefix() default "./";
}
					
				public final class MultiCompositeFieldWidgetMaker extends AbstractWidgetMaker {
	private static final String FIELD_CONFIGS = "fieldConfigs";
	public MultiCompositeFieldWidgetMaker(WidgetMakerParameters parameters) {
		super(parameters);
	}
	@Override
	public DialogElement make() throws ClassNotFoundException, SecurityException, InvalidComponentFieldException,
		NotFoundException, CannotCompileException, NoSuchFieldException, InstantiationException,
		IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException {
		MultiCompositeField multiCompositeFieldAnnotation = getAnnotation(MultiCompositeField.class);
		MultiCompositeFieldWidgetParameters widgetParameters = new MultiCompositeFieldWidgetParameters();
		widgetParameters.setMatchBaseName(multiCompositeFieldAnnotation.matchBaseName());
		widgetParameters.setPrefix(multiCompositeFieldAnnotation.prefix());
		widgetParameters.setFieldName(getFieldNameForField());
		widgetParameters.setFieldLabel(getFieldLabelForField());
		widgetParameters.setFieldDescription(getFieldDescriptionForField());
		widgetParameters.setAdditionalProperties(getAdditionalPropertiesForField());
		widgetParameters.setHideLabel(getHideLabelForField());
		widgetParameters.setName(getNameForField());
		widgetParameters.setAllowBlank(!getIsRequiredForField());
		widgetParameters.setDefaultValue(getDefaultValueForField());
		widgetParameters.setListeners(getListeners());
		widgetParameters.setContainedElements(buildWidgetCollection(multiCompositeFieldAnnotation));
		return new MultiCompositeFieldWidget(widgetParameters);
	}
	
	.
	.
	.
}
					
				@Widget(annotationClass = MultiCompositeField.class, 
	makerClass = MultiCompositeFieldWidgetMaker.class, 
	xtype = MultiCompositeFieldWidget.XTYPE)
public final class MultiCompositeFieldWidget extends AbstractWidget {
	public static final String XTYPE = "multicompositefield";
	private final boolean matchBaseName;
	private final String prefix;
	public MultiCompositeFieldWidget(MultiCompositeFieldWidgetParameters parameters) {
		super(parameters);
		this.matchBaseName = parameters.isMatchBaseName();
		this.prefix = parameters.getPrefix();
	}
	public String getPrefix() {
		return prefix;
	}
	public boolean isMatchBaseName() {
		return matchBaseName;
	}
}