Showing most recent child excerpt on Parent page

Daniel Akrong May 5, 2023

Hi,

I am wondering if there is a way to include an excerpt on the parent page, but one that updates based on the excerpt of the most recent child page. I know that with 'Excerpt Include', I could just edit it to the name of the most recent child page, but is there a way to do it autonomously? Maybe there's a macro that allows me to edit as "Date Created" for the child page or something. 

It doesn't necessarily have to be an excerpt, that's just a good way I know to have highlights on the parent page. If there's another sort of "Text Box", I could use that as well.

Thanks

2 answers

1 accepted

2 votes
Answer accepted
Ken McClean
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
May 5, 2023

To clarify, you want the excerpt on the parent page to match an excerpt on the most recently updated child page?  Or you want the parent page to have an excerpt of the most recent child page?

Daniel Akrong May 5, 2023

To match the excerpt on the most recent child page

Ken McClean
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
May 5, 2023

Hmm okay that's a little more tricky. Let me see if I can put together a macro for you. Might take a day or so.

Daniel Akrong May 5, 2023

That would be great! Thank you

Ken McClean
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
May 7, 2023

I didn't forget about you!

 

Okay so this macro should go on a page that also has the excerpt-include macro on it, and has child pages with the excerpt-include macro on them

The macro (running on the parent page) looks at the most recently updated child page, and gets the settings of the excerpt-include macro on that child page.

It then updates the excerpt-include macro on the parent page to match the child page.


If you want to learn more about how I put it together, I wrote a little blog post about it: https://www.kennethmcclean.com/blog/adventures-in-confluence-macros-1-what-even-is-a-javascript-promise/





//Excerpt-Include Copy Macro
//Copies excerpt-include macro settings from the most recently updated child page, to the parent page
//Author: Ken McClean

//May 7, 2023

## @noparams
<script type="text/javascript">

let pageID = AJS.params.pageId
//Get the ID of the current (parent) page


const baseURL = "/rest/api/content/";
const childrenURL = baseURL + pageID + "/child/page?limit=1000&expand=history.lastUpdated";
//Get the API endpoint with which we will fetch the most recently update child pages

fetch(childrenURL)
.then(response => response.json())

.then(data => {
const sortedChildren = data.results.sort((a, b) => {
const aDate = new Date(a.history.lastUpdated.when);
const bDate = new Date(b.history.lastUpdated.when);
return bDate - aDate;
});
//Return and sort the most recently update child pages

const mostRecentChildID = sortedChildren[0].id;
console.log("The ID of the most recently updated child page is: " + mostRecentChildID);
//Turn the ID of the most recently update child page into a variable

//Start second-level loop
const url = `/pages/viewpage.action?pageId=` + mostRecentChildID;
//Define the URL of the target child page

fetch(url)
.then(response => response.text())

.then(html => {
const div = document.createElement('div');
div.innerHTML = html;

const macroElements = Array.from(div.querySelectorAll(".conf-macro"));

const matchtestMacros = macroElements.filter(macro => macro.getAttribute("data-macro-name") === "excerpt-include");

const macroData = [];

matchtestMacros.forEach(macro => {
const divs = macro.querySelectorAll("div");
const res = divs[0].innerHTML.replace(/<\/?b>/g, "");
macroData.push(res);
});

const ChildMacroSource = macroData[0];
//Get the first excerpt-include macro from the page
//We're assuming that we're only interested in the first result

//Start third-level loop

const pageURL = baseURL + pageID + '?expand=body.storage,version';

// Retrieve the page content
fetch(pageURL)
.then(response => response.json())
.then(data => {
const pageBody = data.body.storage.value;

// Replace "SourcePage" with "NewPage" in the page body
const modifiedPageBody = pageBody.replace(/ri:content-title="([^"]*)"/g, `ri:content-title="${ChildMacroSource}"`);


//Replace the excerpt-include source with the source from the child page

// Update the page with the modified content
const updateURL = baseURL + pageID;
const bodyData = JSON.stringify({
"id": pageID,
"type": "page",
"title": data.title,
"version": {
"number": data.version.number + 1,
"minorEdit": false
},
"body": {
"storage": {
"value": modifiedPageBody,
"representation": "storage"
}
}
});

fetch(updateURL, {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: bodyData
})
.then(response => {
console.log(response);
if (!response.ok) {
throw new Error('Failed to update page content: ' + response);
}
alert('Page content updated successfully');
})
.catch(error => {
alert('Error: ' + error.message);
});
})
.catch(error => alert("Encoutered an error updating the page content: " + error));
//End third-level loop

}).catch(error => console.error("Encoutered an error getting the excerpt-include source from the child page: " + error));
//Second level "then" loop end

}).catch(error => console.log("Error fetching child page ID:", error));
//First level "then" loop end

</script>

 

Daniel Akrong May 7, 2023

Wow this certainly was a lot of effort! Thanks!

Daniel Akrong May 8, 2023

If i wanted to get into making macros, where would I start? Is there some documentation, videos? Instructionals don't seem to be not as widespread as Python per say

Ken McClean
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
May 8, 2023

You'll find that a lot with Atlassian products. There's not a ton of beginner material out there.

Macros seem to be 95% JavaScript. If you learn JS, I think you're most of the way there toward writing macros.   I only just started, myself; this macro that I wrote for you was my second macro project.  But because I'm familiar with Confluence itself, I was able to figure out the rest.

0 votes
Graham Carrick May 16, 2023

I've just launched a App which might be able to help if you are using Confluence Cloud. 

https://marketplace.atlassian.com/apps/1230774/easyinclude?tab=overview&hosting=cloud 

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events