Partner Co-Branding

part of the ArsDigita Community System by Michael Bryzek
Public demonstrations:

What is Co-Branding?

Co-branding refers to the ability to make one page maintain full functionality while swapping in a new look-and-feel. Co-Branding must be easy to do - that is, we do not want to maintain duplicate files for every single co-brand partner... one file should be able to generate multiple look-and-feels with no modification to the single file.

The Big Picture

Many sites market their functionality to other websites - sometimes for money, but always to generate more traffic. A lot of the big sites on the web will only partner with your puny-in-comparison web service if you provide them with your site functionality but maintain the look-and-feel of their website.

The brute force method to doing this is to use the ad-style system and create a separate adp file for every single page you want to co-brand, and for every partner you want to support. This quickly gets out-of-hand if you support more than a couple partners and more than a couple pages.

This partner module lets you co-brand directories, as opposed to individual files, on a partner-by-partner basis. And, once the files in a directory have been set-up to support co-branding, adding another partner takes almost no time at all (about 30 minutes to 4 hours depending on the complexity of the new partner's html templates and the quality of their html). That's the point - in 30 minutes, you can co-brand an entire directory for a new partner. If that directory contains 100 files, you've added templates to 100 files at a rate of 20 seconds per page - that's pretty efficient.

Co-branding works by separating a page into three components:

  1. The Header: This refers to the top and left side of the page including, for example, top graphics, left menu bars, etc.
  2. Page Contents: This refers to the actual contents of the page - the functionality, the features, results of database queries etc. For co-branding to work with the partner module, the Page Contents must be shared by all partners (If you need custom page contents for individual pages, the ad-style system is for you.
  3. The Footer: This refers to the bottom and right side of the page including.

The Medium-Sized Picture

For each directory that you want to cobrand, you add a new "partner" through the Partner Manager. Each partner has some default properties associated with it, such as what fonts to use, what colors to use, etc. The most important property is the Partner Cookie - partner is cookie based. When you add a partner, you specify the name of the cookie you want to use to uniquely identify that partner. When the aolserver starts-up, it registers each of the partner-cookies to redirect requests for any url with starting with that cookie to a procedure that sets a user cookie (named ad_partner) and redirects to whatever page was specified after the cookie.

For example, with GuideStar.org, we have 3 partners:

Note that the final page no longer has the cookie in it!

By using the cookie system, we avoid having to register procs or think about how we create links on our pages - it's all taken care of behind-the-scenes.

Using partner

If your version of acs includes partner, you'll need not configure anything to create your first co-branded page as partner comes with a default profile set up for ArsDigita look and feel. In fact, the entire /admin/partner directory uses the partner system to generate it's own look and feel even though it is not necessary. (partner frees you from ever having to think about page headers and footers while you write your pages).

To Create your first partner page, simply put the following .tcl file anywhere in your file tree:

ReturnHeaders
set page_title "My first co-branded page"
set context_bar [ad_context_bar [list "/index.tcl" "Home"] "Test Page"]
ns_write "
[ad_partner_header]
I just wanted to see what it's like to work with partner
[ad_partner_footer]
"
And that's it!

How this page is processed
The call to ad_partner_header triggers the following sequence of events:

  1. We look at your current url and query the view ad_partner_header_procs to look for tcl procedures that have been registered for that url. Note that we do not require a db handle to be passed as the db handle is only used if necessary.
  2. If we don't find any tcl procedures, we try the parent directory. Eventually we come to the root directory "/" for which partner already registered two procedures (Check the installation script for partner)
  3. partner memoizes the list of procedures to run for your current url to avoid hitting the database next time you request the same url.
  4. partner runs the list of procedures, in the order specified (check out the Partner Manager to see the order). These procedures simple call [ad_header $title] (note title is grabbed from your calling environment) and append some additional html to the result.
  5. The html string is returned.
We process the rest of the page as usual, and then reach the call to ad_partner_footer, which triggers the same sequence of events as for ad_partner_header, except we use the view ad_partner_footer_procs.

To co-brand an existing acs file with:

  1. Use the Partner Manager to register the tcl procedures to run for a given directory
  2. Replace ad_header with ad_partner_header
  3. Replace ad_footer with ad_partner_footer
Note: There is another way to return co-branded pages, which I prefer:
set page_title "My first co-branded page"
set context_bar [ad_context_bar [list "/index.tcl" "Home"] "Test Page"]
set page_body "I just wanted to see what it's like to work with partner"
ns_return 200 text/html [ad_partner_return_template]
ad_partner_return_template simply looks for $page_body and then generates the appropriate page. This way of using the partner system has the added benefit that you can release your database handle(s) before returning any html (just be sure the page loads quickly or else your users will look at a blank screen!).

Under the hood

Parameters File:
[ns/server/vs/acs/partner]
; what is the name of the default partner cookie?
CookieDefault=ad
; All the variables we want to collect  (Any variables added here
; must still be manually added to the data model.)
; Each line of Variable= contains a pipe separated pair of 
; name_of_column in ad_partner | what to display on the add/edit forms
Variable=partner_name|Partner Name
Variable=partner_cookie|Partner Cookie
Variable=default_font_face|Default Font Face
Variable=default_font_color|Default Font Color
Variable=title_font_face|Title Font Face
Variable=title_font_color|Title Font Color
Note that except for group_id, all variables should be listed in the parameters file. We separate group_id to make a nice select box on the UI to easily tie a set of partner parameters to a user_group.

Accessing variables defined in the Partner Manager All the variables you create using the Partner Manager can be accessed in tcl with this call:

[ad_partner_var name_of_column]
ad_partner_var memoizes the result to make retrieving partner variables fast.

Because we use fonts so often, there are two helper procedures to make getting font definitions easy:

proc_doc ad_partner_default_font { {props ""} } {Returns an html font tag with the default font face and default font color filled in from the partner database. If props is nonempty, it is simply included in the font statement} {

    set html "<font face=\"[ad_partner_var default_font_face]\" color=\"[ad_partner_var default_font_color]\""
    if { ![empty_string_p $props] } {
	append html " $props"
    }
    return "$html>"
}

proc_doc ad_partner_title_font { {props ""} } {Returns an html font tag with the default font face and default font color filled in from the partner database. If props is nonempty, it is simply included in the font statement} {
    set html "<font face=\"[ad_partner_var title_font_face]\" color=\"[ad_partner_var title_font_color]\""
    if { ![empty_string_p $props] } {
	append html " $props"
    }
    return "$html>"
}

I don't think there is anything particularly interesting about the Data Model so I've left it in it's own file.

written by mbryzek@arsdigita.com in January 2000