Weird behaviour of body.webresource expansions

Create a page “Page 1” and add an info macro to its body, and then a page “Page 2” without an info macro. The info macro requires a CSS file in order for its export view to be rendered properly. In the following, we will try different ways to retrieve Page 1 and Page 2 through the REST API, using the expansions body.export_view.webresource.tags.css,body.export_view.webresource.uris.css. The expected result is that the info macro CSS file appears in the web resources of Page 1.

Scenarios

1. Single page with an info macro

Fetch Page 1 by accessing /rest/api/search?cql=title="Page%201"&expand=content.body.export_view.webresource.tags.css,content.body.export_view.webresource.uris.css.

The following is returned (trimmed down):

[
    {
        "content": {
            "title": "Page 1",
            "body": {
                "export_view": {
                    "webresource": {
                        "uris": {
                            "css": [
                                "//d1zglhvo4nbro1.cloudfront.net/cdauth.atlassian.net/wiki/s/d41d8cd98f00b204e9800998ecf8427e-CDN/264105304/h/080f35159e8808c1a84075b3ca953e41/_/download/batch/confluence.extra.information:information-plugin-adg-styles/confluence.extra.information:information-plugin-adg-styles.css?externals=__local-default__&relative-url=true"
                            ]
                        },
                        "tags": {
                            "css": "<link type=\"text/css\" rel=\"stylesheet\" href=\"//d1zglhvo4nbro1.cloudfront.net/cdauth.atlassian.net/wiki/s/d41d8cd98f00b204e9800998ecf8427e-CDN/264105304/h/080f35159e8808c1a84075b3ca953e41/_/download/batch/confluence.extra.information:information-plugin-adg-styles/confluence.extra.information:information-plugin-adg-styles.css?externals=__local-default__&amp;relative-url=true\" data-wrm-key=\"confluence.extra.information:information-plugin-adg-styles\" data-wrm-batch-type=\"resource\" media=\"all\">\n<link type=\"text/css\" rel=\"stylesheet\" href=\"//d1zglhvo4nbro1.cloudfront.net/cdauth.atlassian.net/wiki/s/773697523/6452/8993990d819ef6f1244435231fcd06a77e2066f8/1/_/styles/colors.css\" media=\"all\">\n"
                        }
                    }
                }
            }
        }
    }
]

Result: It works as expected, the stylesheet for the info macro is present both in uris and tags. (Although it is a bit weird that the “colors” stylesheet is not listed in uris.)

2. Single page without an info macro

Fetch Page 2 by accessing /rest/api/search?cql=title="Page%202"&expand=content.body.export_view.webresource.tags.css,content.body.export_view.webresource.uris.css.

The following is returned:

[
    {
        "content": {
            "title": "Page 2",
            "body": {
                "export_view": {
                    "webresource": {
                        "uris": {
                            "_expandable": {
                                "all": "",
                                "css": "",
                                "js": ""
                            }
                        },
                        "tags": {
                            "css": "<link type=\"text/css\" rel=\"stylesheet\" href=\"//d1zglhvo4nbro1.cloudfront.net/cdauth.atlassian.net/wiki/s/773697523/6452/8993990d819ef6f1244435231fcd06a77e2066f8/1/_/styles/colors.css\" media=\"all\">\n"
                        }
                    }
                }
            }
        }
    }
]

Result: It kind of works as expected. The info macro stylesheet is not listed. We would expect uris.css to be an empty array (considering that the colors stylesheet never seems to be listed in uris), instead it is not expanded.

3. Multiple pages, first result with an info macro

Now, fetch both pages at once using /rest/api/search?cql=title%20IN%20("Page%201","Page%202")&expand=content.body.export_view.webresource.tags.css,content.body.export_view.webresource.uris.css

The following is returned:

[
    {
        "content": {
            "title": "Page 2",
            "body": {
                "export_view": {
                    "webresource": {
                        "uris": {
                            "_expandable": {
                                "all": "",
                                "css": "",
                                "js": ""
                            }
                        },
                        "tags": {
                            "css": "<link type=\"text/css\" rel=\"stylesheet\" href=\"//d1zglhvo4nbro1.cloudfront.net/cdauth.atlassian.net/wiki/s/773697523/6452/8993990d819ef6f1244435231fcd06a77e2066f8/1/_/styles/colors.css\" media=\"all\">\n"
                        }
                    }
                }
            }
        }
    },
    {
        "content": {
            "title": "Page 1",
            "body": {
                "export_view": {
                    "webresource": {
                        "uris": {
                            "_expandable": {
                                "all": "",
                                "css": "",
                                "js": ""
                            }
                        },
                        "tags": {
                            "css": "<link type=\"text/css\" rel=\"stylesheet\" href=\"//d1zglhvo4nbro1.cloudfront.net/cdauth.atlassian.net/wiki/s/773697523/6452/8993990d819ef6f1244435231fcd06a77e2066f8/1/_/styles/colors.css\" media=\"all\">\n"
                        }
                    }
                }
            }
        }
    }
]

Result: The webresource expansion for “Page 1” are the same as for “Page 2”, even though they should be different. The info macro stylesheet is not listed.

4. Multiple pages, first result without an info macro

Remove the info macro from “Page 1” and add an info macro to “Page 2”.

Now, the following is returned:

[
    {
        "content": {
            "title": "Page 2",
            "body": {
                "export_view": {
                    "webresource": {
                        "uris": {
                            "css": [
                                "//d1zglhvo4nbro1.cloudfront.net/cdauth.atlassian.net/wiki/s/d41d8cd98f00b204e9800998ecf8427e-CDN/264105304/h/080f35159e8808c1a84075b3ca953e41/_/download/batch/confluence.extra.information:information-plugin-adg-styles/confluence.extra.information:information-plugin-adg-styles.css?externals=__local-default__&relative-url=true"
                            ],
                        },
                        "tags": {
                            "css": "<link type=\"text/css\" rel=\"stylesheet\" href=\"//d1zglhvo4nbro1.cloudfront.net/cdauth.atlassian.net/wiki/s/d41d8cd98f00b204e9800998ecf8427e-CDN/264105304/h/080f35159e8808c1a84075b3ca953e41/_/download/batch/confluence.extra.information:information-plugin-adg-styles/confluence.extra.information:information-plugin-adg-styles.css?externals=__local-default__&amp;relative-url=true\" data-wrm-key=\"confluence.extra.information:information-plugin-adg-styles\" data-wrm-batch-type=\"resource\" media=\"all\">\n<link type=\"text/css\" rel=\"stylesheet\" href=\"//d1zglhvo4nbro1.cloudfront.net/cdauth.atlassian.net/wiki/s/773697523/6452/8993990d819ef6f1244435231fcd06a77e2066f8/1/_/styles/colors.css\" media=\"all\">\n",
                        }
                    }
                }
            }
        }
    },
    {
        "content": {
            "title": "Page 1",
            "body": {
                "export_view": {
                    "webresource": {
                        "uris": {
                            "css": [
                                "//d1zglhvo4nbro1.cloudfront.net/cdauth.atlassian.net/wiki/s/d41d8cd98f00b204e9800998ecf8427e-CDN/264105304/h/080f35159e8808c1a84075b3ca953e41/_/download/batch/confluence.extra.information:information-plugin-adg-styles/confluence.extra.information:information-plugin-adg-styles.css?externals=__local-default__&relative-url=true"
                            ],
                        },
                        "tags": {
                            "css": "<link type=\"text/css\" rel=\"stylesheet\" href=\"//d1zglhvo4nbro1.cloudfront.net/cdauth.atlassian.net/wiki/s/d41d8cd98f00b204e9800998ecf8427e-CDN/264105304/h/080f35159e8808c1a84075b3ca953e41/_/download/batch/confluence.extra.information:information-plugin-adg-styles/confluence.extra.information:information-plugin-adg-styles.css?externals=__local-default__&amp;relative-url=true\" data-wrm-key=\"confluence.extra.information:information-plugin-adg-styles\" data-wrm-batch-type=\"resource\" media=\"all\">\n<link type=\"text/css\" rel=\"stylesheet\" href=\"//d1zglhvo4nbro1.cloudfront.net/cdauth.atlassian.net/wiki/s/773697523/6452/8993990d819ef6f1244435231fcd06a77e2066f8/1/_/styles/colors.css\" media=\"all\">\n",
                        }
                    }
                }
            }
        }
    }
]

Result: Again, the webresource expansion for “Page 1” is the same as for “Page 2”, even though they should be different. This time, both pages list the info macro stylesheet.

Conclusion

  • When fetching multiple pages at once through the REST API, the webresource expansion of all the returned pages is set to the one of whichever page is the first result, even if the pages require different web resources.
  • The “colors” stylesheet is not listed in the “webresource.uris” expansion.
  • The “webresource.uris.css” expansion does not work if it contains an empty list.

My goal is to render multiple pages on a single screen. Because of this bug, if some pages contain an info macro and others don’t, these macros are only rendered properly if the first page returned by CQL happens to be one that does contain an info macro.

Workaround

A stable workaround would of course be to fetch each page on its own. However, as I sometimes have to fetch thousands of pages, this is not an option for performance reasons.

I noticed that the webresource.keys expansion works properly and provides output as such:

[
    {
        "content": {
            "title": "Page 2",
            "body": {
                "export_view": {
                    "webresource": {
                        "keys": [
                            "confluence.extra.information:information-plugin-adg-styles"
                        ],
                        "uris": {
                            "css": [
                                "//d1zglhvo4nbro1.cloudfront.net/cdauth.atlassian.net/wiki/s/d41d8cd98f00b204e9800998ecf8427e-CDN/264105304/h/080f35159e8808c1a84075b3ca953e41/_/download/batch/confluence.extra.information:information-plugin-adg-styles/confluence.extra.information:information-plugin-adg-styles.css?externals=__local-default__&relative-url=true"
                            ],
                        },
                        "tags": {
                            "css": "<link type=\"text/css\" rel=\"stylesheet\" href=\"//d1zglhvo4nbro1.cloudfront.net/cdauth.atlassian.net/wiki/s/d41d8cd98f00b204e9800998ecf8427e-CDN/264105304/h/080f35159e8808c1a84075b3ca953e41/_/download/batch/confluence.extra.information:information-plugin-adg-styles/confluence.extra.information:information-plugin-adg-styles.css?externals=__local-default__&amp;relative-url=true\" data-wrm-key=\"confluence.extra.information:information-plugin-adg-styles\" data-wrm-batch-type=\"resource\" media=\"all\">\n<link type=\"text/css\" rel=\"stylesheet\" href=\"//d1zglhvo4nbro1.cloudfront.net/cdauth.atlassian.net/wiki/s/773697523/6452/8993990d819ef6f1244435231fcd06a77e2066f8/1/_/styles/colors.css\" media=\"all\">\n",
                        }
                    }
                }
            }
        }
    },
    {
        "content": {
            "title": "Page 1",
            "body": {
                "export_view": {
                    "webresource": {
                        "keys": [],
                        "uris": {
                            "css": [
                                "//d1zglhvo4nbro1.cloudfront.net/cdauth.atlassian.net/wiki/s/d41d8cd98f00b204e9800998ecf8427e-CDN/264105304/h/080f35159e8808c1a84075b3ca953e41/_/download/batch/confluence.extra.information:information-plugin-adg-styles/confluence.extra.information:information-plugin-adg-styles.css?externals=__local-default__&relative-url=true"
                            ],
                        },
                        "tags": {
                            "css": "<link type=\"text/css\" rel=\"stylesheet\" href=\"//d1zglhvo4nbro1.cloudfront.net/cdauth.atlassian.net/wiki/s/d41d8cd98f00b204e9800998ecf8427e-CDN/264105304/h/080f35159e8808c1a84075b3ca953e41/_/download/batch/confluence.extra.information:information-plugin-adg-styles/confluence.extra.information:information-plugin-adg-styles.css?externals=__local-default__&amp;relative-url=true\" data-wrm-key=\"confluence.extra.information:information-plugin-adg-styles\" data-wrm-batch-type=\"resource\" media=\"all\">\n<link type=\"text/css\" rel=\"stylesheet\" href=\"//d1zglhvo4nbro1.cloudfront.net/cdauth.atlassian.net/wiki/s/773697523/6452/8993990d819ef6f1244435231fcd06a77e2066f8/1/_/styles/colors.css\" media=\"all\">\n",
                        }
                    }
                }
            }
        }
    }
]

This gives us the possibility for a workaround:

  1. We gather a list of all the keys referenced in content.body.export_view.webresource.keys
  2. We filter out the keys for whom a <link> element already exists whose data-wrm-key attribute is set to the respective key.
  3. For the remaining keys, we create a <link> element that points to the stylesheet for this key. We construct the URL for the stylesheet by taking the URL to the colors.css stylesheet listed content.body.export_view.webresource.tags.css and replacing /styles/colors.css at its end with /download/batch/<key>/<key>.css?externals=__local-default__&relative-url=true.

I consider this workaround very hacky, since I am not sure whether the colors.css file is really required by all pages, and whether it will be in the future. Also, the hashes in that URL are wrong, which will probably lead to some caching issues.

2 Likes

Hi @candid,

Thanks for explaining this in so much depth. I have created CONFCLOUD-71603 for the Confluence Cloud team to address.

Regards,
Dugald

1 Like