This tutorial teaches you how to create a simple dynamic content macro module that displays a random image of a cute dog. We're using a dynamic content macro because our macro won't block the rest of the page from loading while it fetches the image.
By the end of this tutorial, you will:
dynamicContentMacros
module to your appLet's get started!
Ensure you have installed all the tools you need for Confluence Connect app development by Getting set up with Atlassian Connect Express (ACE):
The first step is to use atlas-connect
to create the app framework: a directory called macro-tutorial
that contains all the basic components of a Connect app.
1 2atlas-connect new macro-tutorial
macro-tutorial
directory and run npm install
to install
any dependencies for the app.credentials.json
file that gives your app permission to work with your Confluence Cloud
development site. Copy the one you created during the Getting started
tutorial. You can replace or delete the existing credentials.json.sample
file.Take a look around the macro-tutorial
directory. We'll be adding:
atlassian-connect.json
fileroutes
directoryviews
directoryYou add a module by declaring it in your app's atlassian-connect.json
file, also known as the
app descriptor.
Add a dynamicContentMacros
object by pasting the following code over the existing modules
block:
1 2"modules": { "dynamicContentMacros": [ { "url": "/dog", "description": { "value": "Pictures of dogs" }, "name": { "value": "Dog picture" }, "key": "pictures-of-dogs" } ] }
Take note of the following fields:
url
: This is the endpoint your app will use to handle requests for the module. The route handler we'll
add in the next section will handle requests to this URL.name.value
: This is the name that Confluence Cloud shows for your macrokey
: This is a unique identifier for your macroThe key
must be unique across all macros in all apps, so it's normally a good idea to add your app
key as a prefix. We'll skip that step for now.
A route handler is the code that runs when your module's endpoint is called.
In routes/index.js
, add a new app.get()
method under the // Add additional route handlers here…
comment:
1 2// Add additional route handlers here... app.get('/dog', addon.authenticate(), async (req, res) => { const title = 'Random dog'; res.render('dog.hbs', {title}); });
For now, this code is very simple. All it does is render a view called dog
, passing it a title
which is set to "Random dog."
The route handler won't do anything without the view.
To create a simple view, add a file called dog.hbs
in the views
directory, with the following
contents:
1 2{{!< layout}} <div id="dogImage"> <h1>{{title}}</h1> </div>
Notice the following:
dog.hbs
corresponds to the name dog
in the res.render
statement in the route handler.
This is how the route handler finds the view.{{!< layout}}
, makes the new view include everything from layout.hbs
. This is how
you make sure your view includes all the JavaScript you'll need when building a full-featured app.{{title}}
is a placeholder to be filled in by the title
parameter in the res.render
statement.The macro isn't finished yet, but let's test what we've got so far.
macro-tutorial
directory, then type npm start
to start the app.http://127.0.0.1:4040
in a browser and looking for
POST /installed
.You should see Random Dog on your page. Now you're ready to make the app do more.
We'll use the fetch
package to get pictures of dogs.
We'll make some changes to the route handler to get a random dog picture, and a change to the view so that we can display the picture.
fetch
package, type the following at the command line:
1 2npm i node-fetch --save
index.js
, add the following line:
1 2const fetch = require("node-fetch");
/dog
route handler to look like this:
This code uses the1 2app.get('/dog', addon.authenticate(), async (req, res) => { const response = await fetch('https://dog.ceo/api/breeds/image/random'); if(!response.ok) { const textContent = response.text(); console.log(`error while getting random dog picture: ${textContent}`); } const title = 'Random dog'; const jsonContent = await response.json(); const imageUrl = jsonContent.message; res.render('dog', {title, imageUrl}); });
fetch
package to make a request, then parses the returned JSON response to obtain
the URL for an image. We'll pass this URL to the view for rendering.{{title}}
in dog.hbs
, add the following line:
The view should now look like this:1 2<img src="{{imageUrl}}" alt="{{title}}"/>
1 2{{!< layout}} <div id="dogImage"> <h1>{{title}}</h1> <img src="{{imageUrl}}" alt="{{title}}"/> </div>
npm start
to test your app. You should see a new dog picture every time you reload the page.Adding a macro (or any module) is as easy as 1, 2, 3:
atlassian-connect.json
.Now that you know the basic pattern, you can try some of the other tutorials, and experiment with modules such as the content byline item.
Rate this page: