enonic / xp

Enonic XP
https://enonic.com
GNU General Public License v3.0
201 stars 34 forks source link

Embed Fragment as Macro (pageContributions) #6395

Closed ComLock closed 6 years ago

ComLock commented 6 years ago

The code below basically makes it possible to embed any part into an HtmlArea in Content. But is does not work perfectly.

I feel like the concept of part and macro are very similar. If there was built-in functionality to use parts inside HtmlAreas, there might not be much need for macros...

<macro>
    <display-name>Fragment</display-name>
    <description>Displays fragments</description>
    <form>
        <input name="fragmentId" type="ContentSelector">
            <label>Fragment Content</label>
            <occurrences minimum="1" maximum="1"/>
            <config>
                <allowContentType>portal:fragment</allowContentType>
            </config>
        </input>
    </form>
</macro>
import {toStr} from '/lib/enonic/util';
import {get as getContentByKey} from '/lib/xp/content';
import {pageUrl} from '/lib/xp/portal';
import {request as httpClientReq} from '/lib/http-client';

export function macro(req) {
    log.info(toStr({req}));

    const fragmentContent = getContentByKey({key: req.params.fragmentId});
    log.info(toStr({fragmentContent}));

    //const {type, descriptor} = fragmentContent.page.fragment;
    // Requiring part controller runtime will only work within the same app.

    const reqParams = {
        auth: {
            user: 'su',
            password: 'password'
        },
        url: pageUrl({
            id: req.params.fragmentId,
            type: 'absolute'
        })
    };
    log.info(toStr({reqParams}));

    const fragmentRes = httpClientReq(reqParams);
    log.info(toStr({fragmentRes}));

    return fragmentRes;
}
ComLock commented 6 years ago

I would like to avoid writing the same code twice. Aka part and macro.

ComLock commented 6 years ago

The code above is not working correctly because the fragmentUrl includes html head and body...

Is there a componentUrl for fragments?

sigdestad commented 6 years ago

This is not a good solution. I.e. fragments may be layouts, and contain a lot of depending CSS styling. If you want "reusable" content inside a macro, you have to create it as a separate content, not as a fragment.

Also, think what will happen when you have macros inside the fragments again. !