Skip to the content

Exporting and Importing Content Between Umbraco and Confluence

Managing content across multiple platforms can be challenging. If you're using Umbraco for your website and Confluence for documentation, you might find it useful to seamlessly export and import content between these two systems. In this blog post, we'll walk you through the process of exporting a page from Umbraco to Confluence and importing a page from Confluence back to Umbraco.

 

Overview

To achieve this, we'll:

  1. Retrieve page data from Umbraco.
  2. Transform the Umbraco data into a format compatible with Confluence.
  3. Upload images to Confluence.
  4. Create a new page in Confluence with the transformed content.
  5. Fetch page data from Confluence.
  6. Transform the Confluence data back into a format compatible with Umbraco.
  7. Create a new page in Umbraco with the transformed content.

Step 1: Retrieve Page Data from Umbraco

First, we'll fetch the page content from Umbraco, including the grid layout, text, and images.

var contentService = Services.ContentService;
var page = contentService.GetById(pageId);

// Assuming the grid layout data is stored in a property called "grid"
var gridLayout = page.GetValue("grid");
var pageTitle = page.Name;

Step 2: Transform Umbraco Data to Confluence Format

Next, we'll map the grid elements, text, and images from Umbraco to Confluence's storage format (XHTML).

using Newtonsoft.Json.Linq;

var jsonObj = JObject.Parse(gridLayout);
var confluencePageContent = new StringBuilder();
confluencePageContent.Append("< table>< tr>");

foreach (var section in jsonObj["sections"])
{
    foreach (var row in section["rows"])
    {
        confluencePageContent.Append("< tr>");
        foreach (var area in row["areas"])
        {
            confluencePageContent.Append($"< td colspan='{area["grid"]}'>");

            foreach (var control in area["controls"])
            {
                var imageUrl = control["value"]["image"].ToString();
                var caption = control["value"]["caption"].ToString();

                // Assuming UploadImageToConfluence is a method that uploads the image and returns the new URL
                var confluenceImageUrl = UploadImageToConfluence(imageUrl);

                confluencePageContent.Append($"< ac:image ac:width='200'>< ri:attachment ri:filename='{confluenceImageUrl}' />");
                confluencePageContent.Append($"< p>{caption}< /p>");
            }

            confluencePageContent.Append("< /td>");
        }
        confluencePageContent.Append("< /tr>");
    }
}
confluencePageContent.Append("< /table>");

Step 3: Upload Images to Confluence

We'll upload each image to Confluence and get the URL for reference in the content.

private static string UploadImageToConfluence(string imageUrl)
{
    // Implement the logic to upload the image to Confluence and return the new URL
    // Example placeholder URL
    return "confluence-image-url";
}

Step 4: Create Confluence Page

Using Confluence's REST API, we'll create a new page with the transformed content.

var confluencePage = new
{
    type = "page",
    title = pageTitle,
    space = new { key = "SPACE_KEY" },
    body = new
    {
        storage = new
        {
            value = confluencePageContent.ToString(),
            representation = "storage"
        }
    }
};

var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", "base64encoded-credentials");

var response = await httpClient.PostAsync("https://your-confluence-site/rest/api/content",
    new StringContent(JsonConvert.SerializeObject(confluencePage), Encoding.UTF8, "application/json"));

response.EnsureSuccessStatusCode();

Step 5: Fetch Page Data from Confluence

We'll retrieve the page content from Confluence using its REST API.

var confluencePageId = "confluence-page-id";
var response = await httpClient.GetAsync($"https://your-confluence-site/rest/api/content/{confluencePageId}?expand=body.storage");
response.EnsureSuccessStatusCode();

var content = await response.Content.ReadAsStringAsync();
var confluencePage = JObject.Parse(content);
var xhtmlContent = confluencePage["body"]["storage"]["value"].ToString();

Step 6: Transform Confluence Data to Umbraco Format

We'll convert the XHTML content back into the format required by Umbraco, mapping Confluence elements to Umbraco grid elements, text, and images.

var umbracoGrid = new JObject();
var doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(xhtmlContent);

var table = doc.DocumentNode.SelectSingleNode("//table");
var rows = table.SelectNodes("//tr");
foreach (var row in rows)
{
    var umbracoRow = new JObject();
    umbracoRow["name"] = "Row Name";
    umbracoRow["id"] = Guid.NewGuid().ToString();
    umbracoRow["areas"] = new JArray();

    var cells = row.SelectNodes("td");
    foreach (var cell in cells)
    {
        var umbracoArea = new JObject();
        umbracoArea["grid"] = cell.GetAttributeValue("colspan", 1).ToString();
        umbracoArea["controls"] = new JArray();

        var images = cell.SelectNodes(".//ac:image");
        foreach (var image in images)
        {
            var control = new JObject();
            control["value"] = new JObject
            {
                ["image"] = image.SelectSingleNode(".//ri:attachment").GetAttributeValue("ri:filename", ""),
                ["caption"] = "Image Caption"
            };
            umbracoArea["controls"].Add(control);
        }

        umbracoRow["areas"].Add(umbracoArea);
    }

    ((JArray)umbracoGrid["sections"]).Add(umbracoRow);
}

Step 7: Create Umbraco Page

Finally, we'll use Umbraco's API to create a new page with the transformed content, including creating the necessary block controls.

var newPage = contentService.Create("New Page Title", parentId, "documentTypeAlias");
newPage.SetValue("grid", umbracoGrid.ToString());
contentService.SaveAndPublish(newPage);

Important Considerations

  1. Error Handling:

    • Implement robust error handling for API requests and data transformations.
  2. Data Validation:

    • Validate data at each step to ensure it conforms to the expected structure.
  3. Authentication:

    • Securely manage authentication for both Umbraco and Confluence APIs.
  4. Performance:

    • Optimize data processing and API calls to handle large content efficiently.

Conclusion

By following these steps, you can seamlessly export and import content between Umbraco and Confluence, ensuring that your content is accurately transferred and maintains its structure and format. This process can save you time and effort, allowing you to manage your content more effectively across multiple platforms.

About the author

BJ Patel

BJ Patel is an expert user of Umbraco. Always keen to share hints and tips on getting the best out of Umbraco.

comments powered by Disqus

Join Our Community

This is a promo pod

Join Our Community Become a part of our developer community. Share your projects, get feedback, and collaborate with like-minded individuals.

Your contributions help us continue creating valuable content. Consider supporting us by sharing our content.

Junagadh, Gujarat

Support Us.