REST Content Retrieval APIs
Content can be accessed via the REST Content Retrieval APIs. To view the REST Content Retrieval APIs:
or in a new tabNote
Make sure that the request includes the crafterSite
parameter to set a project value. The content
retrieval API’s are project specific, and so, it needs to know the project for each request made.
Here’s an example to get an Item from the content store:
http://localhost:8080/api/1/site/content_store/item.json?url=/site/website/index.xml&crafterSite=mysite
Examples
Below are some examples of creating RESTful services in CrafterCMS.
Render Page Components as JSON
CaaS (Content as a Service) is a common need in today’s multi-channel world. Typically CaaS use cases require that the content is devoid of presentation markup so that the consumer can present the content as it desires. Other times consumers may wish to pull rendered content. This provides a simple REST example (a single Groovy based rest controller script) that will give you a way to render all of the components associated to a page.
Prerequisites
None
Step 1: Create a REST Controller
- Under Scripts/rest right click and click create controller
Enter get-rendered-components.get as the controller name
Add the following code to the controller.
1import java.io.ByteArrayOutputStream
2import java.io.IOException
3import java.io.PrintWriter
4
5import javax.servlet.Filter
6import javax.servlet.FilterChain
7import javax.servlet.FilterConfig
8import javax.servlet.ServletException
9import javax.servlet.ServletOutputStream
10import javax.servlet.ServletRequest
11import javax.servlet.ServletResponse
12import javax.servlet.http.HttpServletRequest
13import javax.servlet.http.HttpServletResponse
14import javax.servlet.http.HttpServletResponseWrapper
15import javax.servlet.WriteListener
16import groovy.util.XmlSlurper
17
18def result = [:]
19def targetPage = params.pageId
20
21if (targetPage != null) {
22 result.page = targetPage
23
24 def pageItem = siteItemService.getSiteItem(targetPage)
25
26 if (pageItem != null) {
27 def componentPaths = pageItem.queryValues("//include")
28 result.components = []
29
30 if (componentPaths != null) {
31 componentPaths.each { componentPath ->
32 if (componentPath.endsWith(".xml") && !componentPath.startsWith("/site/website") ) {
33 logger.info("Including component ${componentPath} into JSON response")
34
35 def component = [:]
36 component.id = componentPath
37
38 // wrap the response to capture the output
39 def wrappedResponse = new CapturingResponseWrapper(response)
40
41 // "include" the page that does the actual work
42 request.getRequestDispatcher("/crafter-controller/component?path=" + componentPath).include(request, wrappedResponse)
43
44 // get the captured output, parse it and prepare the actual response
45 def capturedOut = wrappedResponse.getCaptureAsString()
46
47 component.markup = capturedOut
48
49 result.components.add(component)
50 }
51 }
52 } else {
53 result.message = "No components found"
54 }
55 } else {
56 result.message = "Page '${targetPage}` not found"
57 }
58} else {
59 result.message = "Parameter pageId is required."
60}
61
62return result
63
64protected class CapturingResponseWrapper extends HttpServletResponseWrapper {
65
66 private final ByteArrayOutputStream capture
67 private ServletOutputStream output
68 private PrintWriter writer
69
70 public CapturingResponseWrapper(HttpServletResponse response) {
71 super(response)
72 capture = new ByteArrayOutputStream(response.getBufferSize())
73 }
74
75 @Override
76 public ServletOutputStream getOutputStream() {
77 if (writer != null) {
78 throw new IllegalStateException("getWriter() has already been called on this response.")
79 }
80
81 if (output == null) {
82 output = new ServletOutputStream() {
83
84 @Override
85 public void write(int b) throws IOException {
86 capture.write(b)
87 }
88
89 @Override
90 public void flush() throws IOException {
91 capture.flush()
92 }
93
94 @Override
95 public void close() throws IOException {
96 capture.close()
97 }
98
99 @Override
100 public void setWriteListener(WriteListener writeListener) {
101 }
102
103 @Override
104 public boolean isReady() {
105 return true
106 }
107 }
108 }
109
110 return output
111 }
112
113 @Override
114 public PrintWriter getWriter() throws IOException {
115 if (output != null) {
116 throw new IllegalStateException("getOutputStream() has already been called on this response.")
117 }
118
119 if (writer == null) {
120 writer = new PrintWriter(new OutputStreamWriter(capture, getCharacterEncoding()))
121 }
122
123 return writer
124 }
125
126 @Override
127 public void flushBuffer() throws IOException {
128 super.flushBuffer()
129
130 if (writer != null) {
131 writer.flush()
132 }
133 else if (output != null) {
134 output.flush()
135 }
136 }
137
138 public byte[] getCaptureAsBytes() throws IOException {
139 if (writer != null) {
140 writer.close()
141 }
142 else if (output != null) {
143 output.close()
144 }
145
146 return capture.toByteArray()
147 }
148
149 public String getCaptureAsString() throws IOException {
150 return new String(getCaptureAsBytes(), getCharacterEncoding())
151 }
152
153}
Step 2: Execute the Service
- Open a browser and hit the following URL:
Get the Names of Sites Running in Crafter Engine
In this example we create a simple RESTful service that returns the list of sites running in Crafter Engine. You can find the API for the Context Manager HERE
Prerequisites
None
Step 1: Create a REST Controller
- Under Scripts/rest right click and click create controller
Enter get-sites.get as the controller name
Add the following code to the controller.
1def siteContextManager = applicationContext["crafter.siteContextManager"]
2def siteContextList = siteContextManager.listContexts()
3def siteNames = []
4
5siteContextList.each { siteContext ->
6 def name = siteContext.getSiteName()
7 siteNames.add(name)
8}
9
10return siteNames
Step 2: Execute the Service
- Open a browser and hit the following URL:
Get Pages for a Given Site
In this example we create a simple RESTful service that returns the list of Pages in a site. The service is parameterized to allow the caller to set a starting point and depth.
Prerequisites
None
Step 1: Create a REST Controller
- Under Scripts/rest right click and click create controller
Enter get-pages.get as the controller name
Add the following code to the controller.
1def pathParam = (params.path != null) ? params.path : ""
2def depthParam = (params.depth != null) ? params.depth.toInteger() : 0
3
4def path = "/site/website" + pathParam
5def depth = depthParam != 0 ? depthParam : 2
6
7def navItems = [:]
8def siteDir = siteItemService.getSiteTree(path, depth)
9
10if(siteDir) {
11 def dirs = siteDir.childItems
12 dirs.each { dir ->
13 def dirName = dir.getStoreName()
14 def dirItem = siteItemService.getSiteItem("/site/website/${dirName}/index.xml")
15
16 if (dirItem != null) {
17 def dirDisplayName = dirItem.queryValue('internal-name')
18
19 navItems.put(dirName, dirDisplayName)
20 }
21 }
22}
23
24return navItems
Step 2: Execute the Service
- Open a browser and hit the following URL: