[SalesForce] include component seems to be having issues with merge-field syntax inside of a repeat component

I am trying to place an apex:include inside of an apex:repeat component. But I am getting a compile error:

<apex:repeat value="{!placeholders}" var="placeholder">
  {!placeholder} - {!placeholder.ComponentName__c} <!-- OK -->
  <apex:include pageName="{!pageOne}" /> <!-- OK -->
  <apex:outputText value="{!placeholder.ComponentName__c}" /> <!-- OK -->
  <apex:include pageName="{!placeholder.ComponentName__c}" /> <!--compile error here:  Description  Resource    Path    Location    Type Save error: Unknown property 'ControllerLayoutManager.placeholder' ... -->
</apex:repeat>

There is nothing that I can see in the apex:repeat doco that says it can not handle the apex:include component. I must be missing something. Can anyone offer some insights?

According to a post I found on here, you can not use collections in include parameters. But the author is just guessing by the looks of it.

Best Answer

apex:include resolves its reference before any other element on a page, early in the rendering process. This means that each apex:include will include only one page, and that reference must be non-null before any getters are called. This is different than most other elements, which are executed in page flow order. While this isn't documented, I did some extensive testing.

Test 1

<apex:page controller="xyz">
    <apex:repeat value="{!pageList}" var="aPage">
        <apex:include pageName="{!aPage}"/>
    </apex:repeat>
</apex:page>

This results in "aPage not found".

Test 2

<apex:page controller="xyz">
    <apex:repeat value="{!pageList}" var="aPage">
        <apex:variable name="pageRef" value="{!aPage}"/>
        <apex:include pageName="{!pageRef}"/>
    </apex:repeat>
</apex:page>

This results in "pageRef not found".

Test 3

<apex:component>
    <apex:attribute name="pageName" type="String" description="A page name."/>
    <apex:include pageName="{!pageName}"/>
</apex:component>

This results in "Cannot use apex:include in a component".


I tried a few other nonsensical arrangements, such as trying to use apex:param to call a method repeatedly, which mostly ended in "Page must be set to a non-null value".

I also consulted the documentation, thinking to try a apex:dynamicComponent, which actually explicitly states that a handful of elements have no Apex Code representation: all of them are of a similar logic: "we don't support these elements because they have to compile instead of resolving at run time."

Given that salesforce.com has explictly gone out of their way to block all legitimate attempts of using apex:include dynamically, we must conclude that they have explicitly blocked this functionality.

Finally, given salesforce.com documentation, I often say "If the system doesn't allow something, and the documentation doesn't clearly state that you can, it cannot be done."

Salesforce.com documentation is often positive, focusing on what the system can deliver, and goes out of its way to specifically exclude what the system cannot deliver. Generally, the only pages that describe limitations at all are those pages that speak of clearly defined limits, such as governor limits, API rate limiting, and the such. Any page that covers a feature that has some obscure limitation (such as apex:include not supporting non-static references) usually won't mention it. This is probably one of the most frustrating aspects of salesforce.com development.

Related Topic