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: