Is it possible to do content projection (transclusion) on custom blocks?
Application Type
Reactive
Platform Version
11.13.1 (Build 31652)

I want to create a reusable block that uses a template (say another block) that could be repeated within that block.

For instance, say I want to create a dropdown for which every single custom list item would have a specific rendering with an icon, some text, maybe even clickable links.

With react, I would use props.children to do that. With Angular, I would use content projection a.k.a. transclusion, or I'd pass a ng-template as an input.

For some reason, placeholders cannot be repeated in a block and as a result, wouldn't work there. Any suggestions?

mvp_badge
MVP

Question: what's stopping you from using a list of blocks that receive the content as an input parameter? Of course that would mean somewhat limited functionality in terms of what you could put in the block itself...

A different option could be having a block that receives the data as input parameter as well as the "block type", so you would only render that block type. Of course you have to handle this with IF statements and whatnot...

Am I over simplifying your scenario?

Cheers!

Passing a "block type" might be the first step in the right direction. How would you do that though? I see how a string can be passed but how would you instantiate an actual block out of it?

mvp_badge
MVP

Hi @Alain Chautard & @Armando Gomes,

Late for the party! But here goes my 2cents! :)

@Alain Chautard I understand from where you come, and what you're aiming to do. 

OutSystems being a visual language, you need to create things with a slightly different mindset - due both to the nature and limitations of it. 

Your use case is extremely common - and it's the 101, of developing in OutSystems. 

To make easy to explain, I'll use the following terms:
- creator: the person that is creating an reusable block - you in this case :)
- developer: the person(s) that will be using this block in his(their) application(s) - let's say me and Armando
- user: the person that will be using the application that actually uses the block created by the creator and instantiated by the developer.

As @Armando Gomes already mentioned, we can imagine 2 ways to create this pattern:

  1. A block that receives a list
    In this way, the UI in entirely contained in the block, and the developer using it is only required to pass a list with the information to display (e.g. [{"id": 1, "Name": Rice, "Icon": (url)}, {"id": 2, "Name": "Potato", "Icon": (url)}, ...].
    The block then would have a List widget, that would list the data in the format that the creator defined. This approach would have the following pros-cons:
    + Simple to use by the developer
    + Self contained
    - Hard to customize the ui (I mean, you need to do CSS - hard for many people out there)

    Example of this would be the DropdownTags component of OutSystemsUI.

    In this approach you would NOT use placeholders.

  2. 2 blocks (e.g. combobox + comboboxItem)
    In this approach, your blocks become merely visual/behavioral - but does NOT iterate over data.
    Your block combobox would have a placeholder, and pretty much no logic.
    Your block comboboxItem would define the visual structure for the user, either through simple inputs or through place holders.

    The developer would then, need to drag-n-drop the combobox block, then in the placeholder put a List widget and inside the List widget put the comboboxItem.

    Example of this would be the FloatingActions + FloatingActionsItem component of OutSystemsUI.

    In this approach you WOULD use placeholders.


I'm sorry, for writing so much, and not doing any visual asset to help explain.

Let me know, your thoughts,
Cheers,
RG


p.s. - welcome to OutSystems community!


Thanks @Ruben Goncalves. Option #1 is the closest to what I was thinking about, but it leaves the customization part out of it (or CSS only for the developer).

The idea would be that the block creator opens some of the HTML for its child elements to be customizable, and a placeholder might seem to be the closest to what I'm talking about, but as far as I know, the parent block can't really interact with that content or make it dynamic.


For instance, Angular Material has that possibility to customize a cell in a data table by using any HTML we want as well as custom expressions to render dynamic data in it: https://material.angular.io/components/table/overview#2-define-the-column-templates

That's really what I was hoping to be able to do.

Community GuidelinesBe kind and respectful, give credit to the original source of content, and search for duplicates before posting.