You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by dk...@apache.org on 2019/10/21 19:54:11 UTC

[sling-org-apache-sling-app-cms] branch master updated (7c7a8da -> 0d90273)

This is an automated email from the ASF dual-hosted git repository.

dklco pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-app-cms.git.


    from 7c7a8da  Minor: fixing button on create template
     new 3774ef3  Fixing the permissions for the UGC System user
     new 0d90273  Fixing SLING-8795 - Adding a form action for creating User Generated Content

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../cms/{package-info.java => NameFilter.java}     |  21 +++-
 builder/src/main/provisioning/cms.txt              |   2 +-
 .../operations/PropertyHintNodeNameGenerator.java  |   6 +-
 .../PropertyHintNodeNameGeneratorTest.java         |  80 +++++++++++++
 .../impl/actions/UserGeneratedContentAction.java   | 122 +++++++++++++++++++
 .../{sendemail.json => usergeneratedcontent.json}  |   2 +-
 .../forms/actions/usergeneratedcontent/edit.json   | 133 +++++++++++++++++++++
 .../usergeneratedcontent/usergeneratedcontent.jsp} |  26 +++-
 .../editor/scripts/resourceTypeOptions.jsp         |   1 +
 9 files changed, 380 insertions(+), 13 deletions(-)
 copy api/src/main/java/org/apache/sling/cms/{package-info.java => NameFilter.java} (71%)
 create mode 100644 core/src/test/java/org/apache/sling/cms/core/internal/operations/PropertyHintNodeNameGeneratorTest.java
 create mode 100644 reference/src/main/java/org/apache/sling/cms/reference/forms/impl/actions/UserGeneratedContentAction.java
 copy reference/src/main/resources/jcr_root/apps/reference/components/forms/actions/{sendemail.json => usergeneratedcontent.json} (64%)
 create mode 100644 reference/src/main/resources/jcr_root/apps/reference/components/forms/actions/usergeneratedcontent/edit.json
 copy reference/src/main/resources/jcr_root/apps/reference/components/forms/{providers/userprofile/userprofile.jsp => actions/usergeneratedcontent/usergeneratedcontent.jsp} (53%)


[sling-org-apache-sling-app-cms] 01/02: Fixing the permissions for the UGC System user

Posted by dk...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dklco pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-app-cms.git

commit 3774ef362ce1302ce3f86bb9237e9ea7c479a176
Author: Dan Klco <dk...@apache.org>
AuthorDate: Mon Oct 21 14:10:49 2019 -0400

    Fixing the permissions for the UGC System user
---
 builder/src/main/provisioning/cms.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/builder/src/main/provisioning/cms.txt b/builder/src/main/provisioning/cms.txt
index f4b5393..2beb5a0 100644
--- a/builder/src/main/provisioning/cms.txt
+++ b/builder/src/main/provisioning/cms.txt
@@ -106,7 +106,7 @@
     end
     create service user sling-cms-ugc
     set ACL for sling-cms-ugc
-        allow   jcr:write    on /etc/usergenerated
+        allow   jcr:write,jcr:nodeTypeManagement,jcr:versionManagement    on /etc/usergenerated
     end
     create service user sling-cms-versionmgr
     set ACL for sling-cms-versionmgr


[sling-org-apache-sling-app-cms] 02/02: Fixing SLING-8795 - Adding a form action for creating User Generated Content

Posted by dk...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dklco pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-app-cms.git

commit 0d90273fb41c9b39707b902f52e243a5d03636e5
Author: Dan Klco <dk...@apache.org>
AuthorDate: Mon Oct 21 15:54:02 2019 -0400

    Fixing SLING-8795 - Adding a form action for creating User Generated
    Content
---
 .../main/java/org/apache/sling/cms/NameFilter.java |  36 ++++++
 .../operations/PropertyHintNodeNameGenerator.java  |   6 +-
 .../PropertyHintNodeNameGeneratorTest.java         |  80 +++++++++++++
 .../impl/actions/UserGeneratedContentAction.java   | 122 +++++++++++++++++++
 .../forms/actions/usergeneratedcontent.json        |   5 +
 .../forms/actions/usergeneratedcontent/edit.json   | 133 +++++++++++++++++++++
 .../usergeneratedcontent/usergeneratedcontent.jsp  |  46 +++++++
 .../editor/scripts/resourceTypeOptions.jsp         |   1 +
 8 files changed, 427 insertions(+), 2 deletions(-)

diff --git a/api/src/main/java/org/apache/sling/cms/NameFilter.java b/api/src/main/java/org/apache/sling/cms/NameFilter.java
new file mode 100644
index 0000000..9471b4e
--- /dev/null
+++ b/api/src/main/java/org/apache/sling/cms/NameFilter.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.cms;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Service for filtering an arbitrary string into a Sling-compatible Resource
+ * name.
+ */
+public interface NameFilter {
+
+    /**
+     * Filter the provided name.
+     * 
+     * @param name a String name
+     * @return the Sling-compatible name
+     */
+    @NotNull String filter(@NotNull String name);
+}
diff --git a/core/src/main/java/org/apache/sling/cms/core/internal/operations/PropertyHintNodeNameGenerator.java b/core/src/main/java/org/apache/sling/cms/core/internal/operations/PropertyHintNodeNameGenerator.java
index 06d9770..2be378e 100644
--- a/core/src/main/java/org/apache/sling/cms/core/internal/operations/PropertyHintNodeNameGenerator.java
+++ b/core/src/main/java/org/apache/sling/cms/core/internal/operations/PropertyHintNodeNameGenerator.java
@@ -20,6 +20,7 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.request.RequestParameter;
 import org.apache.sling.api.request.RequestParameterMap;
+import org.apache.sling.cms.NameFilter;
 import org.apache.sling.cms.core.internal.operations.PropertyHintNodeNameGenerator.Config;
 import org.apache.sling.servlets.post.NodeNameGenerator;
 import org.osgi.service.component.annotations.Activate;
@@ -33,9 +34,9 @@ import org.osgi.service.metatype.annotations.ObjectClassDefinition;
  * Custom NodeNameGenerator for generating names based on the value of another
  * named property
  */
-@Component(service = NodeNameGenerator.class, immediate = true)
+@Component(service = { NodeNameGenerator.class, NameFilter.class }, immediate = true)
 @Designate(ocd = Config.class)
-public class PropertyHintNodeNameGenerator implements NodeNameGenerator {
+public class PropertyHintNodeNameGenerator implements NodeNameGenerator, NameFilter {
 
     @ObjectClassDefinition(name = "%cms.name.generator.name", description = "%cms.name.generator.description", localization = "OSGI-INF/l10n/bundle")
 
@@ -67,6 +68,7 @@ public class PropertyHintNodeNameGenerator implements NodeNameGenerator {
         this.replacementChar = config.replacement_char().toCharArray()[0];
     }
 
+    @Override
     public String filter(String nodeName) {
         final StringBuilder sb = new StringBuilder();
         char lastAdded = 0;
diff --git a/core/src/test/java/org/apache/sling/cms/core/internal/operations/PropertyHintNodeNameGeneratorTest.java b/core/src/test/java/org/apache/sling/cms/core/internal/operations/PropertyHintNodeNameGeneratorTest.java
new file mode 100644
index 0000000..d00e58c
--- /dev/null
+++ b/core/src/test/java/org/apache/sling/cms/core/internal/operations/PropertyHintNodeNameGeneratorTest.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.cms.core.internal.operations;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.lang.annotation.Annotation;
+
+import org.apache.sling.cms.core.internal.operations.PropertyHintNodeNameGenerator.Config;
+import org.junit.Test;
+
+public class PropertyHintNodeNameGeneratorTest {
+
+    private PropertyHintNodeNameGenerator generator = new PropertyHintNodeNameGenerator();
+
+    private Config DEFAULT_CONFIG = new Config() {
+
+        @Override
+        public Class<? extends Annotation> annotationType() {
+            return null;
+        }
+
+        @Override
+        public String allowed_chars() {
+            // TODO Auto-generated method stub
+            return "abcdefghijklmnopqrstuvwxyz_-";
+        }
+
+        @Override
+        public String replacement_char() {
+            return "-";
+        }
+
+    };
+
+    @Test
+    public void testFilter() {
+        generator.activate(DEFAULT_CONFIG);
+
+        String filtered = generator.filter("A*dsf--dsfas__sdf_");
+        assertNotNull(filtered);
+        assertEquals("a-dsf--dsfas__sdf_", filtered);
+
+        filtered = generator.filter("A*dsf--dsfas&&sdf*");
+        assertNotNull(filtered);
+        assertEquals("a-dsf--dsfas-sdf-", filtered);
+
+        filtered = generator.filter("*A*dsf--dsfa  s&&sdf*");
+        assertNotNull(filtered);
+        assertEquals("-a-dsf--dsfa-s-sdf-", filtered);
+
+        filtered = generator.filter("");
+        assertNotNull(filtered);
+        assertEquals("-", filtered);
+
+        try {
+            filtered = generator.filter(null);
+            fail();
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+}
diff --git a/reference/src/main/java/org/apache/sling/cms/reference/forms/impl/actions/UserGeneratedContentAction.java b/reference/src/main/java/org/apache/sling/cms/reference/forms/impl/actions/UserGeneratedContentAction.java
new file mode 100644
index 0000000..4292917
--- /dev/null
+++ b/reference/src/main/java/org/apache/sling/cms/reference/forms/impl/actions/UserGeneratedContentAction.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.cms.reference.forms.impl.actions;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.lang3.text.StrSubstitutor;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.jackrabbit.JcrConstants;
+import org.apache.sling.api.resource.PersistenceException;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.cms.CMSConstants;
+import org.apache.sling.cms.NameFilter;
+import org.apache.sling.cms.reference.forms.FormAction;
+import org.apache.sling.cms.reference.forms.FormActionResult;
+import org.apache.sling.cms.reference.forms.FormException;
+import org.apache.sling.cms.reference.forms.FormRequest;
+import org.apache.sling.cms.usergenerated.UGCBucketConfig;
+import org.apache.sling.cms.usergenerated.UserGeneratedContentService;
+import org.apache.sling.cms.usergenerated.UserGeneratedContentService.APPROVE_ACTION;
+import org.apache.sling.cms.usergenerated.UserGeneratedContentService.CONTENT_TYPE;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Component(service = FormAction.class, immediate = true)
+public class UserGeneratedContentAction implements FormAction {
+
+    private static final Logger log = LoggerFactory.getLogger(UserGeneratedContentAction.class);
+
+    @Reference
+    private NameFilter filter;
+
+    @Reference
+    private UserGeneratedContentService ugcService;
+
+    @Override
+    public FormActionResult handleForm(Resource actionResource, FormRequest request) throws FormException {
+        log.trace("handleForm");
+        ValueMap properties = actionResource.getValueMap();
+
+        try {
+            UGCBucketConfig bucketConfig = new UGCBucketConfig();
+            bucketConfig.setAction(
+                    APPROVE_ACTION.valueOf(properties.get("approveAction", APPROVE_ACTION.PUBLISH.toString())));
+            bucketConfig.setBucket(properties.get("bucket", String.class));
+            bucketConfig
+                    .setContentType(CONTENT_TYPE.valueOf(properties.get("contentType", CONTENT_TYPE.OTHER.toString())));
+            bucketConfig.setPathDepth(properties.get("pathDepth", 0));
+
+            log.debug("Creating UGC at with configuration:  {}", bucketConfig);
+            StrSubstitutor sub = new StrSubstitutor(request.getFormData());
+
+            Map<String, Object> contentProperties = new HashMap<>();
+            contentProperties.put(JcrConstants.JCR_PRIMARYTYPE, JcrConstants.NT_UNSTRUCTURED);
+            Arrays.stream(properties.get("additionalProperties", new String[0])).map(v -> {
+                if (v.contains("=")) {
+                    String[] vs = v.split("\\=");
+                    return new ImmutablePair<String, String>(vs[0], vs[1]);
+                } else {
+                    log.warn("Invalid value: {}", v);
+                    return null;
+                }
+            }).forEach(v -> {
+                log.debug("Adding additional property: {}", v);
+                contentProperties.put(v.getLeft(), v.getRight());
+            });
+            contentProperties.putAll(request.getFormData());
+            log.debug("Persisting properties: {}", contentProperties);
+
+            Resource container = ugcService.createUGCContainer(request.getOriginalRequest(), bucketConfig,
+                    sub.replace(properties.get("preview", "")), properties.get("targetPath", ""));
+            log.debug("Using container: {}", container);
+            ResourceResolver resolver = container.getResourceResolver();
+
+            String name = filter.filter(sub.replace(properties.get("name", "")));
+            log.debug("Using name {}", name);
+
+            if (properties.get("wrapPage", false)) {
+                log.debug("Wrapping with page");
+                Resource page = container.getResourceResolver().create(container, name,
+                        Collections.singletonMap(JcrConstants.JCR_PRIMARYTYPE, CMSConstants.NT_PAGE));
+                resolver.create(page, JcrConstants.JCR_CONTENT, contentProperties);
+            } else {
+                log.debug("Creating as direct child");
+                resolver.create(container, name, contentProperties);
+            }
+
+            resolver.commit();
+            log.debug("Successfully persisted UGC");
+            return FormActionResult.success("Created UGC Item");
+        } catch (PersistenceException e) {
+            throw new FormException("Failed to create UGC Content", e);
+        }
+    }
+
+    @Override
+    public boolean handles(Resource actionResource) {
+        return "reference/components/forms/actions/usergeneratedcontent".equals(actionResource.getResourceType());
+    }
+
+}
diff --git a/reference/src/main/resources/jcr_root/apps/reference/components/forms/actions/usergeneratedcontent.json b/reference/src/main/resources/jcr_root/apps/reference/components/forms/actions/usergeneratedcontent.json
new file mode 100644
index 0000000..5b5333c
--- /dev/null
+++ b/reference/src/main/resources/jcr_root/apps/reference/components/forms/actions/usergeneratedcontent.json
@@ -0,0 +1,5 @@
+{
+    "jcr:primaryType" : "sling:Component",
+    "jcr:title": "User Generated Content",
+    "componentType": "Form Action"
+}
\ No newline at end of file
diff --git a/reference/src/main/resources/jcr_root/apps/reference/components/forms/actions/usergeneratedcontent/edit.json b/reference/src/main/resources/jcr_root/apps/reference/components/forms/actions/usergeneratedcontent/edit.json
new file mode 100644
index 0000000..e8a0a19
--- /dev/null
+++ b/reference/src/main/resources/jcr_root/apps/reference/components/forms/actions/usergeneratedcontent/edit.json
@@ -0,0 +1,133 @@
+ {
+    "jcr:primaryType": "nt:unstructured",
+    "sling:resourceType": "sling-cms/components/editor/slingform",
+    "button": "Save",
+    "fields": {
+        "jcr:primaryType": "nt:unstructured",
+        "sling:resourceType": "sling-cms/components/general/container",
+        "approveAction": {
+            "jcr:primaryType": "nt:unstructured",
+            "sling:resourceType": "sling-cms/components/editor/fields/select",
+            "label": "Action",
+            "name": "approveAction",
+            "required": true,
+            "options": {
+                "MOVE": {
+                    "label": "Move",
+                    "value": "MOVE"
+                },
+                "PUBLISH": {
+                    "label": "Publish",
+                    "value": "PUBLISH"
+                }
+            }
+        },
+        "additionalProperties": {
+            "jcr:primaryType": "nt:unstructured",
+            "sling:resourceType": "sling-cms/components/editor/fields/repeating",
+            "label": "Additional Properties",
+            "name": "additionalProperties",
+            "required": false
+        },
+        "bucket": {
+            "jcr:primaryType": "nt:unstructured",
+            "sling:resourceType": "sling-cms/components/editor/fields/text",
+            "label": "Bucket",
+            "name": "bucket",
+            "required": true
+        },
+        "contentType": {
+            "jcr:primaryType": "nt:unstructured",
+            "sling:resourceType": "sling-cms/components/editor/fields/select",
+            "label": "Content Type",
+            "name": "contentType",
+            "required": true,
+            "options": {
+                "COMMENT": {
+                    "label": "Comment",
+                    "value": "COMMENT"
+                },
+                "FORUM_POST": {
+                    "label": "Forum Post",
+                    "value": "FORUM_POST"
+                },
+                "REPLY": {
+                    "label": "Reply",
+                    "value": "REPLY"
+                },
+                "BLOG_POST": {
+                    "label": "Blog Post",
+                    "value": "BLOG_POST"
+                },
+                "CONTACT_FORM": {
+                    "label": "Contact Form",
+                    "value": "CONTACT_FORM"
+                },
+                "SIGNUP": {
+                    "label": "Signup",
+                    "value": "SIGNUP"
+                },
+                "MESSAGE": {
+                    "label": "Message",
+                    "value": "MESSAGE"
+                },
+                "OTHER": {
+                    "label": "Other",
+                    "value": "OTHER"
+                }
+            }
+        },
+        "name": {
+            "jcr:primaryType": "nt:unstructured",
+            "sling:resourceType": "sling-cms/components/editor/fields/text",
+            "label": "Name",
+            "name": "name",
+            "required": true
+        },
+        "pathDepth": {
+            "jcr:primaryType": "nt:unstructured",
+            "sling:resourceType": "sling-cms/components/editor/fields/text",
+            "label": "Path Depth",
+            "name": "pathDepth",
+            "required": true,
+            "type": "number"
+        },
+        "preview": {
+            "jcr:primaryType": "nt:unstructured",
+            "sling:resourceType": "sling-cms/components/editor/fields/textarea",
+            "label": "Preview",
+            "name": "preview",
+            "required": true
+        },
+        "targetPath": {
+            "jcr:primaryType": "nt:unstructured",
+            "sling:resourceType": "sling-cms/components/editor/fields/text",
+            "label": "Target Path",
+            "name": "targetPath"
+        },
+        "wrapPage": {
+            "jcr:primaryType": "nt:unstructured",
+            "sling:resourceType": "sling-cms/components/editor/fields/select",
+            "label": "Wrap in Page?",
+            "name": "wrapPage",
+            "required": true,
+            "options": {
+                "MOVE": {
+                    "label": "Yes",
+                    "value": "true"
+                },
+                "PUBLISH": {
+                    "label": "No",
+                    "value": "false"
+                }
+            }
+        },
+        "wrapPageTypeHint": {
+            "jcr:primaryType": "nt:unstructured",
+            "sling:resourceType": "sling-cms/components/editor/fields/hidden",
+            "name": "wrapPage@TypeHint",
+            "value": "Boolean"
+        }
+    }
+}
+
diff --git a/reference/src/main/resources/jcr_root/apps/reference/components/forms/actions/usergeneratedcontent/usergeneratedcontent.jsp b/reference/src/main/resources/jcr_root/apps/reference/components/forms/actions/usergeneratedcontent/usergeneratedcontent.jsp
new file mode 100644
index 0000000..29c0c60
--- /dev/null
+++ b/reference/src/main/resources/jcr_root/apps/reference/components/forms/actions/usergeneratedcontent/usergeneratedcontent.jsp
@@ -0,0 +1,46 @@
+<%-- /*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */ --%>
+ <%@include file="/libs/sling-cms/global.jsp"%>
+<c:if test="${cmsEditEnabled == 'true'}">
+    <h3>User Generated Content</h3>
+    <dl>
+        <dt>Action</dt>
+        <dd>${properties.approveAction}</dd>
+        <dt>Additional Properties</dt>
+        <dd>
+            <c:if test="${not empty properties.additionalProperties}">
+                ${fn:join(properties.additionalProperties,', ')}
+            </c:if>
+        </dd>
+        <dt>Bucket</dt>
+        <dd>${properties.bucket}</dd>
+        <dt>Content Type</dt>
+        <dd>${properties.contentType}</dd>
+        <dt>Name</dt>
+        <dd>${properties.name}</dd>
+        <dt>Path Depth</dt>
+        <dd>${properties.pathDepth}</dd>
+        <dt>Preview</dt>
+        <dd>${properties.preview}</dd>
+        <dt>Target Path</dt>
+        <dd>${properties.targetPath}</dd>
+        <dt>Wrap in Page?</dt>
+        <dd>${properties.wrapPage}</dd>
+    </dl>
+</c:if>
\ No newline at end of file
diff --git a/ui/src/main/resources/jcr_root/libs/sling-cms/components/editor/scripts/resourceTypeOptions.jsp b/ui/src/main/resources/jcr_root/libs/sling-cms/components/editor/scripts/resourceTypeOptions.jsp
index 89cbb3a..5a05237 100644
--- a/ui/src/main/resources/jcr_root/libs/sling-cms/components/editor/scripts/resourceTypeOptions.jsp
+++ b/ui/src/main/resources/jcr_root/libs/sling-cms/components/editor/scripts/resourceTypeOptions.jsp
@@ -21,6 +21,7 @@
 <c:forEach var="type" items="${fn:split(param.availableTypes,',')}">
     <optgroup label="${sling:encode(type,'HTML_ATTR')}">
         <c:set var="query" value="SELECT * FROM [sling:Component] WHERE [componentType]='${type}' ORDER BY [jcr:title]" />
+        ${query}
         <c:forEach var="component" items="${sling:findResources(resourceResolver,query,'JCR-SQL2')}">
             <c:choose>
                 <c:when test="${fn:startsWith(component.path,'/apps/')}">