[SalesForce] Force.com Sites Page to template to component relationship

I am looking for the best way to set dynamic attributes for a component that is included on a Force.com site template page, but varies from page to page.

For example, let's say I have a Home Page, a Search Page, an Info Page and a Contact Us Page. In my header component (Visualforce Component) I have an attribute to specify the "active tab" so that I can set the class to "active".

Since my component is defined on the template page rather than the actual content page, I am curious to know how I may set that value?

Am I approaching this in the right manner, or is there a better way to accomplish my task?

I have listed sample Visualforce code below to demonstrate my issue.

Template (Visualforce Page)

<apex:page showHeader="false"
    controller="TemplateController">
    <apex:insert name="header">
        <c:Header
            IsAuthenticatedUser="{!NOT(ISPICKVAL($User.UserType,'Guest'))}"
            ActiveTab="{!ActiveTab}" AllowSearchLink="{!CanSearch}" />
    </apex:insert>

    <apex:insert name="body" />

    <apex:insert name="footer">
        <c:Footer />
        <site:googleAnalyticsTracking />
    </apex:insert>

</apex:page>

Home Page (Visualforce Page)

<apex:page showHeader="false" title="{!$Label.SiteTitle}" 
    cache="false" contoller="HomeController">
    <apex:composition template="{!$Site.Template}">
        <apex:define name="body">  
             <h1>
                 {!$Label.SiteTitle}
             </h1>
        </apex:define>
    </apex:composition>
</apex:page>

Header (Visualforce Component)

<apex:component id="headerComponent">
<apex:attribute name="IsAuthenticatedUser" type="boolean"
    description="" default="false" />
<apex:attribute name="AllowSearchLink" type="boolean" description=""
    default="false" />
<apex:attribute name="ActiveTab" type="string" description=""
    default="" />
<ul id="nav">
    <li class='{!IF(ActiveTab="Home", "active", "")}'><a
        href="{!URLFOR($Page.HomePage)}"><span>{!$Label.Home}</span></a></li>
    <apex:outputPanel rendered="{!IsAuthenticatedUser}" layout="none">
        <apex:outputPanel layout="none" rendered="{!AllowSearchLink}">
            <li class='{!IF(ActiveTab="Search", "active", "")}'><a
                href="{!URLFOR($Page.SearchPage)}"><span>{!$Label.SearchLink}</span></a></li>
        </apex:outputPanel>
        <li class='{!IF(ActiveTab="Info", "active", "")}'><a
            href="{!URLFOR($Page.InfoPage)}"><span>{!$Label.Info}</span></a></li>
    </apex:outputPanel>
    <li class='{!IF(ActiveTab="ContactUs", "active", "")}'><a
        href="{!URLFOR($Page.ContactUs)}"><span>{!$Label.ContactUs}</span></a></li>
</ul>

Best Answer

The way that I've handled this in the past is to use the apex:variable component in conjunction with the composition template.

For example, I have a site where every page needs to display the same image except for the home page.

In my home page, I define some content for the template that sets up a variable:

<apex:define name="imageoverride">
    <apex:variable var="imgover" value="true"/>
</apex:define>

and then in my templated page I have:

<apex:variable var="imgover" value="false"/>
<apex:insert name="imageoverride" />

which means that after this point, for every page aside from the home page, the imgover variable will contain the value 'false', but for the home page it will have the value 'true'. I can then inspect this and take appropriate action:

<apex:outputPanel layout="none" rendered="{!imgover=='false'}">
   <!-- render the standard image -->
</apex:outputPanel>

<apex:outputPanel layout="none" rendered="{!imgover=='true'}">
   <!-- render the content that replaces the image -->
</apex:outputPanel>

In your case I think it should just be a matter of each page having an apex:define that sets a variable of activeTab to the appropriate value ('Home', 'Contact' etc).