i recently started a confluence cloud project using atlassian connect express.
but i couldn't use any method to include a stylesheet into my macros
here is my index.js
module.exports = function (app, addon) {
// Root route. This route will serve the `atlassian-connect.json` unless the
// documentation url inside `atlassian-connect.json` is set
app.get('/', function (req, res) {
res.format({
// If the request content-type is text-html, it will decide which to serve up
'text/html': function () {
res.redirect('/atlassian-connect.json');
},
// This logic is here to make sure that the `atlassian-connect.json` is always
// served up when requested by the host
'application/json': function () {
res.redirect('/atlassian-connect.json');
}
});
});
// This is an example route that's used by the default "generalPage" module.
// Verify that the incoming request is authenticated with Atlassian Connect
app.get('/hello-world', addon.authenticate(), function (req, res) {
// Rendering a template is easy; the `render()` method takes two params: name of template
// and a json object to pass the context in
res.render('hello-world', {
title: 'Atlassian Connect'
//issueId: req.query['issueId']
});
}
);
// Add any additional route handlers you need for views or REST resources here...
// Render the background-color macro.
app.get('/v1/backgroundColor',addon.authenticate(), function(req, res){
// Grab all input parameters - sent through to us as query params.
var color = req.query['color'],
pageId = req.query['pageId'],
pageVersion = req.query['pageVersion'],
macroHash = req.query['macroHash'],
userKey = req.query['user_key'];
var clientKey = req.context.clientKey;
console.log(" ----- clientKey : ", clientKey);
console.log(" ----- userKey : ", userKey);
// Execute API request to get the macro body.
getHTTPClient(clientKey, userKey).get(
'/rest/api/content/' + pageId +
'/history/' + pageVersion +
'/macro/hash/' + macroHash,
function(err, response, contents){
console.log(" ----- response status: ", response.statusCode);
// If we've encountered errors, render an error screen.
if(err || (response.statusCode < 200 || response.statusCode > 299)) {
console.log(err);
res.render('<strong>An error has occurred :( '+ response.statusCode +'</strong>');
}
console.log(" ----- contents : ", contents);
// Parse the response, and send the body through.
contents = JSON.parse(contents);
// Render with required body.
res.render('background-color', { body : contents.body, color: color });
}
);
});
app.get('/v1/progressbar',addon.authenticate(), function(req, res){
// Grab all input parameters - sent through to us as query params.
var steps = req.query['steps'],
currentstep = req.query['currentstep'],
pageId = req.query['pageId'],
pageVersion = req.query['pageVersion'],
macroHash = req.query['macroHash'],
userKey = req.query['user_key'];
var clientKey = req.context.clientKey;
console.log(" ----- clientKey : ", clientKey);
console.log(" ----- userKey : ", userKey);
// Execute API request to get the macro body.
getHTTPClient(clientKey, userKey).get(
'/rest/api/content/' + pageId +
'/history/' + pageVersion +
'/macro/hash/' + macroHash,
function(err, response, contents){
console.log(" ----- response status: ", response.statusCode);
// If we've encountered errors, render an error screen.
if(err || (response.statusCode < 200 || response.statusCode > 299)) {
console.log(err);
res.render('<strong>An error has occurred :( '+ response.statusCode +'</strong>');
}else{
console.log(" ----- contents : ", contents);
// Parse the response, and send the body through.
contents = JSON.parse(contents);
// Render with required body.
res.render('progress-bar', { body : currentstep, color: steps });
}
}
);
});
// load any additional files you have in routes and apply those to the app
{
var fs = require('fs');
var path = require('path');
var files = fs.readdirSync("routes");
for(var index in files) {
var file = files[index];
if (file === "index.js") continue;
// skip non-javascript files
if (path.extname(file) != ".js") continue;
var routes = require("./" + path.basename(file));
if (typeof routes === "function") {
routes(app, addon);
}
}
}
function getHTTPClient (clientKey, userKey){
return addon.httpClient({
clientKey : clientKey,
userKey : userKey,
appKey : addon.key
});
}
};
my macro handlebar file
{{!< layout}}
{{!--
If we have received a macro body, render it.
Otherwise, show a preview screen/message.
--}}
<div>
<ol class="aui-progress-tracker">
<li class="aui-progress-tracker-step" style="width:25%"><span>Configure instance</span></li>
<li class="aui-progress-tracker-step aui-progress-tracker-step-current" style="width:25%"><span>Select plugins</span>
</li>
<li class="aui-progress-tracker-step" style="width:25%"><span>Invite users</span></li>
<li class="aui-progress-tracker-step" style="width:25%"><span>Confirm</span></li>
</ol>
</div>
my layout.hbs
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="ap-local-base-url" content="{{localBaseUrl}}">
<title>{{title}}</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="//aui-cdn.atlassian.com/aui-adg/6.0.9/js/aui.min.js"></script>
<link rel="stylesheet" href="//aui-cdn.atlassian.com/aui-adg/6.0.9/css/aui.min.css" media="all">
<link rel="stylesheet" href="//aui-cdn.atlassian.com/aui-adg/6.0.9/css/aui-experimental.min.css" media="all">
<script src="//aui-cdn.atlassian.com/aui-adg/6.0.9/js/aui-experimental.min.js"></script>
<script src="//aui-cdn.atlassian.com/aui-adg/6.0.9/js/aui-datepicker.min.js"></script>
<script src="//aui-cdn.atlassian.com/aui-adg/6.0.9/js/aui-soy.min.js"></script>
<!--[if IE 9]><link rel="stylesheet" href="//aui-cdn.atlassian.com/aui-adg/5.9.21/css/aui-ie9.css" media="all"><![endif]-->
<link rel="stylesheet" href="{{furl '/css/addon.css'}}" type="text/css" />
<script src="{{hostScriptUrl}}" type="text/javascript"></script>
</head>
<body class="aui-page-hybrid">
<section id="content" role="main">
{{{body}}}
</section>
<script src="{{furl '/js/addon.js'}}"></script>
</body>
</html>
and my css file which contains the defined classes
/* add-on styles */
.intro-header h1 {
font-size: 48px;
line-height: 60px;
padding-top: 20px;
}
.intro-header p.subtitle {
font-size: 24px;
line-height: 30px;
padding-bottom: 20px;
}
.main-panel .aui-page-panel-item {
padding: 20px 40px 20px 0;
height: 100px;
}
/* SFM styles */
/* Layout */
.aui-progress-tracker {
display: table;
font-size: 12px;
margin: 10px 0 0;
padding: 0;
table-layout: fixed;
word-wrap: break-word; /* doesn't work in IE */
}
.aui-progress-tracker:first-child {
margin-top: 0;
}
.aui-progress-tracker-step {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
display: table-cell;
padding: 0 10px;
max-width: 140px;
min-width: 80px;
text-align: center;
}
/* Progress Bar */
.aui-progress-tracker-step > span,
.aui-progress-tracker-step > a {
display: block;
font-weight: bold;
outline: none;
padding-top: 25px;
position: relative;
}
.aui-progress-tracker-step > span:before,
.aui-progress-tracker-step > a:before {
background: #3b73af;
border-radius: 100%;
box-shadow: 0 0 0 3px #f5f5f5; /* can't just use a 3px border as an IE9 bug causes it to draw a strange additional darker border on the outside in addition to the 3px border */
content: "";
height: 10px;
left: 50%;
margin-left: -5px;
position: absolute;
top: 3px;
width: 10px;
}
.aui-progress-tracker-step + .aui-progress-tracker-step > span:after,
.aui-progress-tracker-step + .aui-progress-tracker-step > a:after {
background: #3b73af;
border: solid #f5f5f5;
border-width: 2px 0;
box-shadow: -5px 0 0 -2px #3b73af, 5px 0 0 -2px #3b73af;
content: "";
height: 4px;
left: -50%;
margin-left: -14px; /* almost touches right edge of previous dot (leaves 1px room for rounding widths like 33.3% in webkit) */
margin-right: 6px; /* almost touches left edge of this dot (leaves 1px room for rounding widths like 33.3% in webkit) */
position: absolute;
right: 50%;
top: 4px;
}
.aui-progress-tracker-step-current ~ .aui-progress-tracker-step {
color: #707070;
}
.aui-progress-tracker-step-current ~ .aui-progress-tracker-step > span:before,
.aui-progress-tracker-step-current ~ .aui-progress-tracker-step > a:before {
background-color: #ccc;
}
.aui-progress-tracker-step-current ~ .aui-progress-tracker-step > span:after,
.aui-progress-tracker-step-current ~ .aui-progress-tracker-step > a:after {
background-color: #f5f5f5;
box-shadow: none;
}
/* Inverted Colours */
.aui-progress-tracker-inverted .aui-progress-tracker-step > span:before,
.aui-progress-tracker-inverted .aui-progress-tracker-step > a:before {
box-shadow: 0 0 0 3px #fff;
}
.aui-progress-tracker-inverted .aui-progress-tracker-step + .aui-progress-tracker-step > span:after,
.aui-progress-tracker-inverted .aui-progress-tracker-step + .aui-progress-tracker-step > a:after {
border-color: #fff;
}
.aui-progress-tracker-inverted .aui-progress-tracker-step-current ~ .aui-progress-tracker-step > span:after,
.aui-progress-tracker-inverted .aui-progress-tracker-step-current ~ .aui-progress-tracker-step > a:after {
background-color: #fff;
}
/* Interaction wih page layout */
.aui-page-header-actions .aui-progress-tracker {
float: right;
}
Online forums and learning are now in one easy-to-use experience.
By continuing, you accept the updated Community Terms of Use and acknowledge the Privacy Policy. Your public name, photo, and achievements may be publicly visible and available in search engines.