Your SlideShare is downloading. ×



Published on

Published in: Software, Technology, Business

1 Like
  • Be the first to comment

No Downloads
Total Views
On Slideshare
From Embeds
Number of Embeds
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

No notes for slide


  • 1. CIRCUIT AN ADOBE DEVELOPER EVENT PRESENTED BY CITYTECH, INC. Use SlingQuery and walk the tree with ease Tomek Rękawek, Cognifide @TomaszRekawek
  • 2. Sling API Resource parent = myResource.getParent(); for (Resource child : parent.getChildren()) { if (child.adaptTo(ValueMap.class).containsKey("myProperty")) { //... } } efficient, especially for denormalized and well- structured content[1] easy to use but: a lot of while()s, iterators and nullchecks code complexity is growing fast [1] Efficient content structures and queries in CRX
  • 3. Sling example Find the first ancestor with a given template. String path = "/content/geometrixx/en/products/triangle/jcr:content/par"; String homeTemplate = "/apps/geometrixx/templates/homepage"; Resource resource = resourceResolver.getResource(path); while ((resource = resource.getParent()) != null) { if (!resource.isResourceType("cq:Page")) { continue; } ValueMap map = resource.adaptTo(ValueMap.class); String cqTemplate = map.get("jcr:content/cq:template"); if (homeTemplate.equals(cqTemplate)) { break; } } resource.getPath();
  • 4. SlingQuery example import static$; Resource resource = getResource("/content/geometrixx/en/products/triangle/jcr:content/par"); $(resource) .closest("cq:Page[jcr:content/cq:template=/apps/geometrixx/templates/homepage]") $()is a valid method name in Java, it wraps resource(s) into an iterable SlingQuery collection each method transforms the existing collection into a new one API inspired by jQuery
  • 5. Get all text components from the parsys r = getResource("/content/geometrixx/en/jcr:content/rightpar/teaser") SlingQuery collection = $(r) .closest("cq:PageContent") .find("foundation/components/parsys#par") .children("foundation/components/text") for (Resource c : collection) { println c.path } each method returns new collection SlingQueryobject implements Iterable
  • 6. Breadcrumbs r = getResource("/content/geometrixx/en/products/mandelbrot/overview/jcr:content/par") Iterable<Page> breadcrumbs = $(r) .parents("cq:Page") .not("[jcr:content/hideInNav=true]") .map(Page.class) for (Page p : breadcrumbs) { println p.title } map()method creates a new Iterable<> adapting each resource to a given class resource.adaptTo(Page.class) approach compatible with Sling Models
  • 7. Selector string r = getResource("/content/geometrixx/en/products/mandelbrot") $(r) .children("cq:PageContent") .children("foundation/components/parsys") .children("#title[jcr:title=Best in class][type=large]:first") selector format resource type or node type #resource-name attributes in [] modifiers, each prepended by : all elements are optional
  • 8. Advanced selectors r = getResource("/content/geometrixx") $(r) .find("[text*=square]:not(cq:PageContent):first") .closest("cq:Page") .find("#title, #image, #par:parent") :not()accepts any valid selector :not(:not(:not(:first))) :parent- only resources having children there is a number of operators for square brackets alternatives can be separated with a comma
  • 9. Random image rnd = new java.util.Random() r = getResource("/content/dam/geometrixx/travel") $(r) .children("dam:Asset") .filter({ rnd.nextFloat() > 0.9 } as Predicate) .first() in Java it'd look like this: // ... .filter(new Predicate<Resource>() { @Override public boolean accepts(Resource resource) { return rnd.nextFloat() > 0.9; } });
  • 10. Siblings but not me r = getResource("/content/geometrixx/en/products/mandelbrot/jcr:content/par/image") myPage = $(r).closest("cq:Page") result = myPage .siblings("cq:Page") .not(myPage) the SlingQuery collection is immutable each method returns a new collection any Iterable<Resource>may be used as a filter
  • 11. Find all pages with given template $(resourceResolver) .find("cq:PageContent[cq:template=/apps/geometrixx/templates/homepage]") .parent() $(resourceResolver)creates a collection containing / find()iterates over the whole subtree
  • 12. Search strategy r = getResource("/content/geometrixx/en") result = $(r) .searchStrategy(DFS) .find("cq:Page") for (Resource c : result) { println c.path } strategies: DFS, BFS, QUERY QUERYtries to rewrite find()selector into JCR- SQL2 the result is filtered once more
  • 13. Find method vs JCR find()is powerful but may be dangerous it should be used only for small subtrees if you want to query a large space, use JCR-SQL[2] or XPath if your SlingQuery processes more than 100 resources, you'll get a warning in the logs: 28.05.2014 13:35:49.942 *WARN* [0:0:0:0:0:0:0:1 [1401276949857] POST /bin/groovy console/post.json HTTP/1.1] SlingQuery Number of processed resources exceeded 10 0. Consider using a JCR query instead of SlingQuery. More info here: http://git. io/h2HeUQ
  • 14. Laziness result = $(resourceResolver) .searchStrategy(DFS) .find() .slice(10, 20) result.toString() we don't query resources unless we need them invoking the SlingQuery method adds a new function to the chain functions are executed by the final iterator (like the one created by the for()loop) all functions are lazy expect the last()function
  • 15. Resources code & docs global Maven repository <dependency> <groupId>com.cognifide.cq</groupId> <artifactId>sling-query</artifactId> <version>1.4.4</version> </dependency>
  • 16. Questions?
  • 17. Thank you!