Yes this is not very clearly documented the data types that reside behind the Visualforce Global Variables i totally agree. As such I can only give you the benefit of my experience in the past on figuring this out and few other examples in the documentation that support it.
Mapping Bindings to Methods
In respect to the $CurrentPage variable, this on first sight might appear to expose the instance methods PageReference data type, which was my first thought. However it's not always an exact science unfortunately. Typically once you establish the connection between the Apex system type (which is documented) and the global variable, you can remove the 'get' prefix from the methods and using them in your dot notation to access the information. Though in this case i don't think this is whats happening for $CurrentPage unfortunately, leaving us reliant on the examples in the docs and forums to derive.
$ObjectType Further Insight?
The classic one that has historically generated the most questions is $ObjectType, i now see that Salesforce has started to offer an explanation of the above and clarification of what it calls as a 'sub set' (mainly the getter methods) of the information exposed from the underlying Apex type (DescribeSObjectResult in this case).
Binding to Maps returned from Global Variable underlying Methods
Finally in respect to getter methods on underlying types, which return a Map, you can read up on how Visualforce generally handles these here. Which i thought would confirm the use of this syntax, {!$CurrentPage.parameters.relatedId} (since PageReference.getParameters() returns a Map). However looking at the docs around $ObjectType, the square bracket syntax is also valid, so i would have expected {!$CurrentPage.parameters['relatedId']} to also work, but it does not. Further confirming a lack of underlying relationship with PageReference.
Summary
It seems that in some cases if we know the underlying Apex system type we can use some rules and observations to find other information. This appears to be somewhat supported by the $ObjectType example, though my gut feel is $CurrentPage is bound to some internal type and not PageReference, since {!$Currentpage.anchor} yields an error on save.
Reading literally the paragraph of documentation for $CurrentPage, i can conclude that the only supported fields are $CurrentPage.Name, $CurrentPage.URL and $CurrentPage.parameteters, though as above, experimentation may yield others.
In short i would advise (via the doc feedback feature at the bottom of the docs) to encourage Salesforce to continue to expand out the information available on the Global Variables as they have done on $ObjectType quite well.
Let me answer my question.
It is possible using meta data describe pagelayout method.
<apex:outputPanel id="zoneFilter" layout="none">
<h2 class="zoneLabel">Zone </h2>
<select title="Choose a Zone" style="width:22%;" onchange="$('#zoneHidden input:first-child').val(this.value); changeDependentList(this.options[this.selectedIndex].innerHTML);">
<option value="{!strZoneId}">{!strZoneName}</option>
<apex:repeat id="repZone" value="{!lstZone}" var="objZone" >
<apex:outputPanel id="optionZone" rendered="{!LOWER(objZone['label']) != LOWER(strZoneName)}" layout="none">
<option value="{!objZone['value']}">{!objZone['label']}</option>
</apex:outputPanel>
</apex:repeat>
</option>
</select>
<span id="zoneHidden"><apex:inputHidden value="{!strZoneId}" /></span>
</apex:outputPanel>
<apex:outputPanel id="categoryFilter" layout="none">
<h2>Category </h2>
<select title="Choose a Categories" id="category" style="width:22%;" onchange="$('#categoryHidden input:first-child').val(this.value);">
</select>
<span id="categoryHidden"><apex:inputHidden value="{!strCategoryName}" /></span>
</apex:outputPanel>
<apex:outputPanel id="statusFilter" layout="none">
<h2 class="statusLabel">Status </h2>
<select title="Choose a Status" id="status" style="width:22%;" onchange="$('#statusHidden input:first-child').val(this.value);" >
</select>
<span id="statusHidden"><apex:inputHidden value="{!strStatusName}" /></span>
</apex:outputPanel>
<script>
recordTypeMap = new Array();
var recordTypeToStatus = [];
var recordTypeToCategory = [];
onloadPage();
function onloadPage()
{
sforce.connection.sessionId = '{!$Api.Session_ID}';
// here in array we can send Record type Ids but it was giving some time wrong result , so blank array give result for all available //RecordType detail
//result = sforce.connection.describeLayout('Idea', new Array('099394343400034'));
result = sforce.connection.describeLayout('Idea', new Array());
recordTypeName = new Array();
recordTypeMap = result.recordTypeMappings;
recordTypeMap.forEach(function(obj){
recordTypeName.push(obj.name.substring(0,obj.name.indexOf(':')).toUpperCase());
});
recordTypeName.pop();
recordTypeName.push('ALL');
for(i=0;i<recordTypeMap.length;i++)
recordTypeToStatus.push({'name':recordTypeName[i],'status': getName(recordTypeMap[i].picklistsForRecordType[1])});
for(i=0;i<recordTypeMap.length;i++)
recordTypeToCategory.push({'name':recordTypeName[i],'categories': getName(recordTypeMap[i].picklistsForRecordType[0])});
changeDependentList('{!strZoneName}');
}
function getName(MainList)
{
var modiflist = new Array();
if(MainList.picklistValues.length == undefined)
modiflist.push(MainList.picklistValues.label);
else
{
MainList.picklistValues.forEach(function(obj){
modiflist.push(obj.label);
});
}
return modiflist;
}
function changeDependentList(zoneName)
{
console.log(recordTypeName);
console.log(zoneName.toUpperCase());
indexToChange = recordTypeName.indexOf(zoneName.toUpperCase());
if(indexToChange != -1){
var statusList = recordTypeToStatus[indexToChange];
console.log($('#statusHidden input:first-child').val());
var currentStatus = $('#statusHidden input:first-child').val();
console.log(statusList.status);
$('#status').empty(); //removing old childs
var $ele1 = $('#status');
if(statusList.status.indexOf(currentStatus) == -1)
{
$ele1.append($('<option value="All">All</option>'));
}
else
$ele1.append($('<option value='+currentStatus+'>'+currentStatus+'</option>'));
statusList.status.forEach(function(statusToAdd){
$ele1
.append($("<option></option>")
.attr("value", statusToAdd)
.text(statusToAdd)
);
});
var categoryList = recordTypeToCategory[indexToChange];
$('#category{!id}').empty(); //removing old childs
var $ele2 = $('#category');
$ele2.append($('<option value="All">All</option>'));
categoryList.categories.forEach(function(statusToAdd){
$ele2
.append($("<option></option>")
.attr("value", statusToAdd)
.text(statusToAdd)
);
});
}
}
</script>
Best Answer
Natalia, your question actually answered my question, which was how to get the Community ID to my Apex controller for a Visualforce component. I think you have answered your own question, which is to create a base controller that all of your site controllers will extend, so that every page can have access to the Community ID.
The base controller would look something like the following:
Then, just make sure all of your controllers for the site in question extend this base controller.