I’ve done this two ways:
1) – a csv export function – detect that special content type handling is required BEFORE wp outputs anything.
add_action ('plugins_loaded', 'amr_meta_handle_csv');
function amr_meta_handle_csv ($csv, $suffix='csv') {
// chcek if there is a csv request on this page BEFORE we do anything else ?
if (( isset ($_POST['csv']) )) {
// do some stuff
to_csv ($csv, $suffix)
}
}
function to_csv ($csv, $suffix) {
/* create a csv file for download */
if (!isset($suffix)) $suffix = 'csv';
$file="userlist-".date('YmdHis').'.'.$suffix;
header("Content-Description: File Transfer");
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=$file");
header("Pragma: no-cache");
header("Expires: 0");
echo $csv;
exit(0); /* Terminate the current script sucessfully */
}
Another way was more feed oriented, but same principle, except wp does the special handling detection (checks for ?feed=ics or ). Put the add_feed code in an init action.
add_feed('ics', 'ical_feed');
function ‘ical_feed’ then does the whole header etc.