One of the most frequent customizations required is that of the Contribution pages, used for everything from Donations to Memberships to Pledges. Modifications are done to the .tpl Smarty templates, mostly in <<civicrm>>CRM/Contribute/Form/Contribution.  If you can't find the file you are looking for, look at the includes in the Main.tpl for clues or use AstroGREP on Windows to search the code for the text you want to change.

Before you continue, read and understand everything on this page, most importantly how to create custom tpl and php directories so you don't overwrite your changes each time you upgrade CiviCRM, and how to create changes for specific numbered pages only, not every Contribution page.

Below you'll find a working list of all my changes, mostly in <<civicrm>>CRM/Contribute/Form/Contribution, that I've made to this pages, and how I did them:

To change the recurring donation frequency/duration selector to a simplified unlimited monthly recurring

Replace line 80 with this:

<td>{$form.is_recur.html} every month<br />
<input type="hidden" value="month" name="frequency_unit" id="frequency_unit">

Add a "same as billing" option to your form, if you use the Name and Address profile on the page as well.

Add this after

{include file='CRM/Core/BillingBlock.tpl'}

in <<civicrm_custom_tpl>>CRM/Contribute/Form/Contribution/Main.tpl

function copyAddress(sameAsBilling) {
	var firstName = document.getElementById('billing_first_name').value;
	var lastName = document.getElementById('billing_last_name').value;
	var streetAddress = document.getElementById('billing_street_address-5').value;
	var city = document.getElementById('billing_city-5').value;
	var stateProvince = document.getElementById('billing_state_province_id-5').value;
	var postalCode = document.getElementById('billing_postal_code-5').value;
	var country = document.getElementById('billing_country_id-5').value;
	var copy_firstName = document.Main.first_name;
	var copy_lastName = document.Main.last_name;
	var copy_streetAddress = document.getElementById('street_address-Primary');
	var copy_city = document.getElementById('city-Primary');
	var copy_stateProvince = document.getElementById('state_province-Primary');
	var copy_postalCode = document.getElementById('postal_code-Primary');
	var copy_country = document.getElementById('country-Primary');

	if (sameAsBilling.checked) {
		/* if (copy_firstName) alert(document.Main.first_name.value); */
		if (copy_firstName) copy_firstName.value = firstName;
		if (copy_lastName) copy_lastName.value = lastName;
		if (copy_streetAddress) copy_streetAddress.value = streetAddress;
		if (copy_city) copy_city.value = city;
		if (copy_stateProvince) copy_stateProvince.value = stateProvince;
		if (copy_postalCode) copy_postalCode.value = postalCode;
		if (copy_country) copy_country.value = country;
	} else {
		if (copy_firstName) copy_firstName.value = "";
		if (copy_lastName) copy_lastName.value = "";
		if (copy_streetAddress) copy_streetAddress.value = "";
		if (copy_city) copy_city.value = "";
		if (copy_stateProvince) copy_stateProvince.value = "";
		if (copy_postalCode) copy_postalCode.value = "";
		if (copy_country) copy_country.value = "";

<input type="checkbox" id="same_as_billing" value="" onClick="copyAddress(this)">
<label for="same_as_billing">Membership address is the same as the billing address.</label>

Change the wording on the Billing Block "Billing First Name" etc.

Rather than edit the PHP code, edit this file: CRM/Core/BillingBlock.tpl to something more appealing.

                        <div class="section {$}-section">
							<div class="label">First Name</div>
                            <div class="content">{$form.billing_first_name.html}</div>
                            <div class="clear"></div>
                        <div class="section {$}-section">
							<div class="label">Middle Name</div>
                            <div class="content">{$form.billing_middle_name.html}</div>
                            <div class="clear"></div>
                        <div class="section {$}-section">
							<div class="label">Last Name</div>
                            <div class="content">{$form.billing_last_name.html}</div>
                            <div class="clear"></div>

Show and hide different contribution amounts based on $_GET parameters

This is kind of an advanced hack you do to a .tpl file to show or hide certain contribution options. Let's say, in this example, that you want certain contribution amounts to be hidden for a Personal Contribution Page, but shown on a normal view of a Contribution Page

First of all this javascript will get the "label" <label for="ID#here"> for a contribution amount. It's notoriously hard to get modify labels using CSS alone, so this is a way around that.

<script language="javascript">
var labels = document.getElementsByTagName('LABEL');
for (var i = 0; i < labels.length; i++) {
    if (labels[i].htmlFor != '') {
         var elem = document.getElementById(labels[i].htmlFor);
         if (elem)
            elem.label = labels[i];                     

Then using that code, you can select a label and use standard javascript to hide it. This is not jQuery, this is just reqular javascript. jQuery's method isn't entirely cross browser compatible, and chokes on certain browsers. This gets around that. The problem is that IDs of these contribution amounts CHANGE whenever you edit the amount OR the label. This is a really annoying thing about CiviCRM, but means people shouldn't be editing the contribution amounts after you make the pages.

{* this hides the registrant fee if on a PCP page *}
{if $smarty.get.pcpId}
<script language="javascript">
document.getElementById('CIVICRM_QFID_369__25_00') = 'none';
document.getElementById('CIVICRM_QFID_369__25_00').style.display = 'none';


<script language="javascript">
document.getElementById('CIVICRM_QFID_370__20_00') = 'none';
document.getElementById('CIVICRM_QFID_370__20_00').style.display = 'none';

document.getElementById('CIVICRM_QFID_371__50_00') = 'none';
document.getElementById('CIVICRM_QFID_371__50_00').style.display = 'none';

document.getElementById('CIVICRM_QFID_372__100_0') = 'none';
document.getElementById('CIVICRM_QFID_372__100_0').style.display = 'none';

document.getElementById('CIVICRM_QFID_373__1000_') = 'none';
document.getElementById('CIVICRM_QFID_373__1000_').style.display = 'none';